Ex22 How to break it

i have been trying to access variables from the update_ratio function in ex22.c from main in ex22_main.c , how can i do it? (i tried with a double pointer and with a function pointer.)

and deleted the extern from THE_SIZE in ex22.h and got no warnings or errors.

You might need to declare that variable extern in order to access it. If you can add a paste or gist from github I can take a look.

this code changed nothing -

 4 // makes THE_SIZE in ex22.c available to other .c files - taking down extern to see errors - this didn't work 
  5  int THE_SIZE;

as you can see i was able to access THE_AGE via THE_SIZE although THE_AGE is not extern, but i was enable to access ratio from the update_raio function -

  /** trying to access the static variable ratio from ex22.c
 26           *log_warn("accessing radio from function update_rati()");
 27           *log_info("radio value: %e", *ratio_ptr);     
 28           * didnt work
 29         */
 30         /** trying to make a pointer to the function and from there accessing ratio
 31           *double (*func_hack)(double new_ratio) = update_ratio;
 32           *log_warn("trying to access ratio from pointer: %f", *(func_hack+1));
 33           * didnt work
 34           */
 35 
 36         // test out THE_AGE 
 37         log_info("My name is %s, age %d",MY_NAME, get_age());
 38 
 39         /** accessing THE_AGE directly
 40           * log_info("THE_AGE : %s", THE_AGE);
 41           */
 42         // trying to access THE_NAME throught THE_SIZE pointer
 43         int* size_ptr = &THE_SIZE;
 44         log_info("THE_AGE: %d", *(size_ptr+1)); // worked

When you put code here you need to do this:

[code]
Palomar puts code here.
[/code]

Then everyone can read it. Or use https://gist.github.com/ and you should definitely post all of your code for me to see. I think what you’re doing is super wrong, and a horrible ugly hack that will cause you tons of pains and errors. Please show your code.

I’ve struggled with the same issue, and may have attempted a similarly super wrong and horribly ugly hack - so in an effort to limit the number of times this is asked (and hopefully answered), here are the details of my troubles:

Attempt 1 (the following lines represent the only change to the main function in ex22_main.c - no other files have been changed from the provided source in the book):

// Try to access ratio
double *ratio = &(update_ratio(1.0));
log_info("ratio is %f", ratio);

This results in the following error:

ex22_main.c:51:21: error: lvalue required as unary ‘&’ operand

My suspicion is that this approach couldn’t hope to work because update_ratio, as defined in ex22.c, is just returning a constant double value (for this invocation of the function anyway)… an rvalue rather than the expected lvalue.

Attempt 2 changes a bunch:
in ex22.c:

double *update_ratio(double new_ratio) {
    static double ratio = 1.0;

    double old_ratio = ratio;

    ratio = new_ratio;
 
    return &old_ratio;
}

and in ex22_main.c (in the main function):

// Try to access ratio
double *ratio = update_ratio(1.0);
log_info("ratio is %f", *ratio);

Result:

[amartinez@titanium ex22]$ cc -Wall -g -DNDEBUG -c -o ex22.o ex22.c && cc -Wall -g -DNDEBUG 
ex22_main.c ex22.o -o ex22_main
ex22.c: In function ‘update_ratio’:
ex22.c:24:12: warning: function returns address of local variable [-Wreturn-local-addr]
     return &old_ratio;
            ^~~~~~~~~~

Along with a segfault on execution. This is also not the right way to break it, though broken it certainly is. My hope was that I’d be able to get at the actual value of ratio from inside update_ratio, but that doesn’t appear to be the case.

At any rate, I’ve exhausted my attempts at Google/StackOverflow, manpages, and gdb. If anyone can shed some light down the right path I’d appreciate it, as I’m sure the OP would as well.

Sorry for the late reply, take a look at @ajmartinez follow-up as it has some good stuff. But, the thing I think you’re running into is that each platform will do linking a little differently, and it’s possible that your compiler simply doesn’t care that the variable is not extern. I just say skip this for now, and then if you run into you in error later where it claims it cannot find a variable, and that variable is defined in some other place, then you know it’s probably a problem with extern.