Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

Unused variable warnings- type pointer

Rusty

Active Coder
I am using pointers, in part, to modify variables passed to functions by reference. The compiler generates warnings of unused variables that I believe I am in fact using, though indirectly. I thought I understood how to use and code pointers, at least a little. But evidently not?

The program builds/runs fine otherwise and results are correct.

Reasonable user inputs:
1) 10
2) 0.1
3) 20
4) 760
5) 5000

Why am I getting warnings? Is my pointer syntax adequate but wrong?

Thanks for any insight.

ps I've attached a text file of main.c because I'm unable to paste the code into code brackets. Too many lines maybe?
 

Attachments

Your code looks very solid and I think you well understand how to work with pointers. The fact at the code works correctly proves that.
It would be useful to see your compiler output, because I am getting no warnings in the Visual Studio C compiler (except for scanfbeing unsafe and you should be using scanf_s). What compiler are you using ? Any specific compiler switches ?
If you use a variable indirectly through pointers, a compiler will not always be able to detect that. That I don't get any warnings doesn't prove my Visual Studio compiler is that smart, more likely it is just less fussy (by default) than your compiler.
If the warnings annoy you, as they would do me, you could always just initialize these specific variables. Or perhaps there's a pragma or compiler switch to suppress them.
As for posting in code brackets, did you use the </> button ?
 
Looking at your code some I readily spotted see two unused variables. In main() you have this

C:
double eth_mol1 = 0;
double *peth_mol1 = &eth_mol1;

double boil_pt1 = 80; // Seed temp to saturated pressure calc Degrees C
double *pboil_pt1 = &boil_pt1;

but you are nowhere using these two pointers peth_mol1 and pboil_pt1. Why define them ? Are you just a little too fond of pointers, I wonder ?
Now it really puzzles me that the Visual Studio compiler does not report these as unused 🤔
 
Screenshot (160).pngScreenshot (160).png
Really struggling here this morning. Tried several times to insert the screenshot of warnings with earlier post. Now I have two. 🤔

I'm using CodeBlocks with GNU GCC compiler. Yes did use code thingy </> as per code I posted recently. Select C language and tried to paste in window at line 1. Nothing happened. Press 'continue' button and then tried to paste in
C:
like here. No luck. Copied text from both CB editor and saved version through Notepad. No luck pasting it. I was able to paste a subset maybe 20 lines. That's why I thought maybe a limit on size. Appreciate you alls review. This is a major rewrite of a considerably smaller version. I've always been able to eliminate warnings but previous version did not include the use of pointers. I didn't have a grasp of them back then.
 
Maybe this is where I don't understand. *peth_mol1 passed to initial_conditions as formal argument in definition. But passed to function call as &eth_mol1 as actual argument. If I said that correctly. Similar with pboil_pt1 in bp_by_t function
 
I found that I needed to set warning level 4 to get these warnings. Now I'm getting the same set:
Code:
1>D:\dotnet\projects\frutc\frutc.c(82,10): warning C4189: 'peth_mol1': local variable is initialized but not referenced
1>D:\dotnet\projects\frutc\frutc.c(75,7): warning C4189: 'pwatts': local variable is initialized but not referenced
1>D:\dotnet\projects\frutc\frutc.c(73,7): warning C4189: 'pstart_temp': local variable is initialized but not referenced
1>D:\dotnet\projects\frutc\frutc.c(72,10): warning C4189: 'pstart_abv': local variable is initialized but not referenced
1>D:\dotnet\projects\frutc\frutc.c(79,10): warning C4189: 'ph2o_gram1': local variable is initialized but not referenced
1>D:\dotnet\projects\frutc\frutc.c(74,7): warning C4189: 'patm_press': local variable is initialized but not referenced
1>D:\dotnet\projects\frutc\frutc.c(85,10): warning C4189: 'pboil_pt1': local variable is initialized but not referenced
1>D:\dotnet\projects\frutc\frutc.c(71,10): warning C4189: 'pstart_vol': local variable is initialized but not referenced

From the warning text it follows that my suggestion to initialize these things is not sufficient to get rid of the warnings. It seems that your compiler is explicitly requesting them by using the -Wunused-variable parameter.

The first warning is the first one I mentioned. As I said, you are not using the peth_mol1 variable ! Yes, it points to the eth_mol1 variable which you do use, but that does not make the pointer itself being used or even referenced. You need to make up your mind whether you want to pass variables by value or by reference (i.e. through a pointer). If you pass by value, no need to declare a pointer. That statement is completely redundant.
Pointers are great to pass structs, arrays, functions, etc. but there's no point in using them for primitive types. Unless you want a function to modify an argument (ugh...) then you need to pass a pointer rather than the value itself.

I hope that clarifies a bit !
 
C:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MMW 18.0153   //Molar mass of water Grams per mol
#define MME 46.0684   //Molar mass of ethanol Grams per mol
#define GAL2L 3.7854  //Gallons to Liters conversion
#define W_DENS 0.998  //Water density at 20 degrees C
#define E_DENS 0.789  //Ethanol density at 20 degrees C
#define LHV_W 2257   //latent heat of vaporisation of water in joules\gram\K
#define LHV_E 855     //latent heat of vaporisation of ethanol in joules\gram\K
#define CPE 2.845     //Specific heat ethanol
#define CPW 4.184     //Specific heat of water


/***********************************************************/
//Antoine Eq coefficients
double eA = 7.68117;
double eB = 1332.04;
double eC = 199.2;

double wA = 8.07131;
double wB = 1730.63;
double wC = 233.426;

//CONVERSION COEFFICIENTS
static const double abw_abv[9] = /*Array of E Croissants coefficients for conversion of alcohol by weight to alcohol by volume*/
{
-0.000039705486746795932, 1.2709666849144778, -0.40926819348115739, 2.0463351302912738,
-7.8964816507513707, 15.009692673927390, -15.765836469736477, 8.8142267038252680, -2.0695760421183493
};


/**DECLARE FUNCTIONS********************************************************/

void get_user_input(double *pstart_vol, double *pstart_abv, int *start_temp, int *atm_press, int *watts);

//Converts alcohol by volume to alcohol by weight
double abv_to_abw(double abv);

//Calculates mass and mols of mixture*/
void initial_conditions(double start_vol, double abv, double (*abv_to_abw)(double abv),
                        double *peth_gram1, double *ph2o_gram1, double *peth_mol1);

//van Laar ctivity coefficient applied to liquid phase of Raoults Law
//x1 is molar fraction of ethanol. x2 is molar fraction of water (1-x1)
double calc_gamma_e(double x1, double x2);
double calc_gamma_w(double x1, double x2);

//Calculate saturated vapor pressure per Antoine equation by temperature
double calc_psat_t(double A, double B, double C, double *boil_pt1, double gamma, double x);

//Calculate boil point by iterating temperature
void bp_by_t(double atm_p, double *boil_pt1, double *eth_mol1,
               double (*calc_gamma_e)(double x1, double x2),
               double (*calc_gamma_w)(double x1, double x2),
               double (*calc_psat_t)(double A, double B, double C, double *temp, double gamma, double x));

//Calculate time to boil
void time2boil(double start_temp, double boil_pt1, int watts, double eth_gram1, double h2o_gram1);
/*********************************************************/

int main()
{
//User input data
    double start_vol, start_abv = 0;
    int start_temp, atm_press, watts = 0;

    double *pstart_vol = &start_vol;
    double *pstart_abv = &start_abv;
    int *pstart_temp = &start_temp;
    int *patm_press = &atm_press;
    int *pwatts = &watts;

//Initial conditions data
    double eth_gram1, h2o_gram1 = 0;
    double *ph2o_gram1 = &h2o_gram1;

    double eth_mol1 = 0;
    double *peth_mol1 = &eth_mol1;

    double boil_pt1 = 80; // Seed temp to saturated pressure calc Degrees C
    double *pboil_pt1 = &boil_pt1;

    get_user_input(&start_vol, &start_abv, &start_temp, &atm_press, &watts);
//Check user input
//printf("\n1 = %lf \n2 = %lf \n3 = %d \n4 = %d \n5 = %d", start_vol, start_abv, start_temp, atm_press, watts);


    initial_conditions(start_vol, start_abv, abv_to_abw, &eth_gram1, &h2o_gram1, &eth_mol1);
//Check initial conditions
//printf("\neth mass = %lf grams \nh2o mass = %lf grams \neth mols = % lf mols ", eth_gram1, h2o_gram1, eth_mol1);


    bp_by_t(atm_press, &boil_pt1, &eth_mol1,  calc_gamma_e, calc_gamma_w, calc_psat_t);
//Check boil point
//printf("\nfirst boil point = %lf", boil_pt1);

    time2boil(start_temp, boil_pt1, watts, eth_gram1, h2o_gram1);

    return 0;
}

/*********FUNCTION DEFINITIONS**********/
void get_user_input(double *pstart_vol, double *pstart_abv, int *pstart_temp, int *patm_press, int *pwatts)
 {
   printf("\nEnter Pot liquid volume (gal): ");
   scanf("%lf", pstart_vol);

   printf("\nEnter Pot liquid ABV (0 to 1): ");
   scanf("%lf", pstart_abv);

   printf("\nEnter Start Temperature C: ");
   scanf("%d", pstart_temp);

   printf("\nEnter Atmospheric Pressure Hg/mm: ");
   scanf("%d", patm_press);

   printf("\nEnter Heatup Power Watts: ");
   scanf("%d", pwatts);

   return;
}

/***************************************************/

/*Calculates alcohol by weight from alcohol by volume. Source: On the Conversion of Ethanol by Edwin Croissant 02-14-2016 */
/*Result between 0 and 1. Valid only for input between 0 and 1 and valid only at 20 degrees C*/
/*Initial polynomial y = a + b*x + c*x^2 + d*x^3 + f*x^4 + g*x^5 + h*x^6 + i*x^7 + j*x^8*/

double abv_to_abw(double abv)
{
    const double a =  0.00018684999875047631;
    const double b =  0.77602465132552556;
    const double c =  0.41803095099103116;
    const double d = -2.5221614925275091;
    const double f =  9.5827123045656251;
    const double g = -19.928886159385002;
    const double h =  24.165120890385651;
    const double i = -15.830262207383321;
    const double j =  4.3390473620304988;

//In Horner form
    double temp = j;
    temp = temp * abv +i;
    temp = temp * abv +h;
    temp = temp * abv +g;
    temp = temp * abv +f;
    temp = temp * abv +d;
    temp = temp * abv +c;
    temp = temp * abv +b;
    double abw = temp * abv +a;

    return abw;
}
/*****************************************************************/

void initial_conditions(double start_vol, double abv, double (*abv_to_abw)(double abv),
                        double *peth_gram1, double *ph2o_gram1, double *peth_mol1)
{
   //Convert alcohol by volume to alcohol by wight (wt%-wt%)
   double abw = 0;
   abw = abv_to_abw(abv);

   //Calculate component mass of mixture
   *peth_gram1 = start_vol * abw * GAL2L * 1000 * E_DENS;
   *ph2o_gram1 = start_vol * (1-abw) * GAL2L * 1000 * W_DENS;


   //Convert alcohol by weight to alcohol by mol (mol fraction)
   *peth_mol1 = abw /(abw +MME /MMW *(1-abw));

   return;
}

/************************************************/
/*Calculate Van Laar activity coefficient for ethanol*/
double calc_gamma_e(double x1, double x2)
{
double const a12 = 1.68811;/*a12 and a21 are Van Laar activity model constants*/
double const a21 = 0.95268;
double result = exp((a12 * pow(x2, 2)) / (pow(((a12 * x1 / a21) + x2), 2)));
return (result);
}


/***************************************************/
/*Calculate Van Laar activity coefficient for water*/
double calc_gamma_w(double x1, double x2)
{
double const a12 = 1.68811;
double const a21 = 0.95268;
double result = exp((a21 * pow(x1, 2)) /  (pow(((a21 * x2 / a12) + x1), 2)));
return (result);
}


/***************************************************/
//Antoine Eq. to calculate saturated vapor pressure for water and ethanol
double calc_psat_t(double A, double B, double C, double *temp, double gamma, double x)
{
double psat = x*gamma*pow(10, (A-((B)/(C + *temp))));
return psat;
}

/***************************************************/
void bp_by_t(double atm_p, double *pboil_pt1, double *peth_mol1,
               double (*calc_gamma_e)(double x1, double x2),
               double (*calc_gamma_w)(double x1, double x2),
               double (*calc_psat_t)(double A, double B, double C, double *temp, double gamma, double x))
{
   double x1 = *peth_mol1;     //ethanol component of mixture in mols
   double x2 = 1-x1;           //water component
   double psat1 = 0;
   double psat2 = 0;
   double gamma_e = 0;
   double gamma_w = 0;

   gamma_e = calc_gamma_e(x1, x2);
   gamma_w = calc_gamma_w(x1, x2);
    do
    {
        psat1 = calc_psat_t(eA, eB, eC, pboil_pt1, gamma_e, x1);  //Saturated vapor pressure ethanol
        psat2 = calc_psat_t(wA, wB, wC, pboil_pt1, gamma_w, x2);  //Saturated vapor pressure water
        *pboil_pt1 += 0.001;
    }
    while (psat1 + psat2 < atm_p); //When sum of vapor pressures = or exceed atmospheric pressure the mixture is boiling

    printf("\npressure = %lf", psat1 +psat2);
    return;
}

/*****************************************************************/
void time2boil(double start_temp, double boil_pt1, int watts, double eth_gram1, double h2o_gram1)
{
   double power_req, temp_rise, minutes = 0;

   //Calc specific heat. CPE&W are global constants of specific heat of ethanol and water respectively
   double pot_mass = eth_gram1 + h2o_gram1;
   double spec_heat = (eth_gram1/pot_mass *CPE) + (h2o_gram1/pot_mass *CPW);

   temp_rise = boil_pt1 - start_temp;
   power_req = pot_mass *spec_heat *temp_rise;

   minutes = power_req /watts /60;
   printf("\ntime to boil = %.1lf", minutes);

   return;
}

Not sure what your problem is with posting your code in code tags - it works like a charm !
If there is a limit (there always is one) then you are probbaly nowhere near it.
 
Screenshot (165).png

I appreciate your patience and assistance. My purpose of passing variables by reference is to modify and return more than one variable in a function. It seems get_user_input works properly in that regard. Or no?

The pass by reference value of *peth_mol1 to the function "initial conditions" modifies the variable eth_mol1 that is outside that function.
In main eth_mol1 is initialized to zero. After the function is executed eth_mol1 takes the value 0.0329 as shown in screen shot.
So the variable *peth_mol1 IS passing and modifying its pointed to value, it seems to me.
In other words, the compiler is mis-reporting unused variables.
This is such a fundamental point to my understanding of pointers that I'm at a total loss if wrong.

I take your point about compiler settings- that is a bit of heavy lifting at this point. Feel like I'm punching above my weight as it is. I'm willing to live with warnings now.

A second point: I have it in my mind that it is good practice for main() to be as succinct as possible. Ultimately I'd planned for main() to consist only of 6 functions, besides variable initialization. I guess I may be rethinking that.

Code pasting... ARGHHH. No issues with it on Friday or previously- today- not so much. Even got booted off a couple times "OOPS We've encountered a problem".

Thanks again. I am always appreciative of the gift of time involved in providing assistance
Don
 
I appreciate your patience and assistance. My purpose of passing variables by reference is to modify and return more than one variable in a function. It seems get_user_input works properly in that regard. Or no?
Yes. If your function needs to modify an argument variable, you need to pass that value by reference. Which you do. All fine.

The pass by reference value of *peth_mol1 to the function "initial conditions" modifies the variable eth_mol1 that is outside that function.
In main eth_mol1 is initialized to zero. After the function is executed eth_mol1 takes the value 0.0329 as shown in screen shot.
So the variable *peth_mol1 IS passing and modifying its pointed to value, it seems to me.
NO !! You are not passing peth_mol1 to your function, you are passing &eth_mol1. Sure, it's the same value, but to the compiler it's a different thing. Do me a favor and simply remove these two lines from your code in main() :

C:
double *peth_mol1 = &eth_mol1;
double *pboil_pt1 = &boil_pt1;

and you'll see that it works just as well and with two less warnings. These two variables really are not used in your main() function. Your problem is, I think, that you have named this parameter double *peth_mol1 in your function declaration. Although that works (what's in a name, right ?) this suggests that we now have a pointer to a pointer, which is not so. You should declare the function as

C:
void initial_conditions(double start_vol, double abv, double (*abv_to_abw)(double abv),
                        double *eth_gram1, double *h2o_gram1, double *eth_mol1)

without the p's, and adjust the function code accordingly. Same for some other functions that take reference arguments.


In other words, the compiler is mis-reporting unused variables.
No, it isn't ! As I hope may be clear by now.

I take your point about compiler settings- that is a bit of heavy lifting at this point. Feel like I'm punching above my weight as it is. I'm willing to live with warnings now.
Never live with warnings if you can help it ! Good programming should result in a clean compilation. Warnings are given for a reason, and they should always make you think about what you are doing there. In this case they are easily fixed, just by removing all these superfluous pointer definitions. The only warnings I've ever ignored are those about pointers that don't point to the same object type. You get that often in old style legacy code which makes heavy use of pointers, and sometimes there are just too darn many to fix.

A second point: I have it in my mind that it is good practice for main() to be as succinct as possible. Ultimately I'd planned for main() to consist only of 6 functions, besides variable initialization. I guess I may be rethinking that.
No rule says that main() should be as short as possible. But it is good practice not to put tons of code inside main(). And that holds for any function really ! If a function does not fit on the screen or page, it is probably too long. But it is not a hard rule of course. Having tons of functions with only a couple of lines is just as annoying and hard to oversee as having functions that go on and on for many pages. It's a balance you need to find.

Code pasting... ARGHHH. No issues with it on Friday or previously- today- not so much. Even got booted off a couple times "OOPS We've encountered a problem".
That sounds like the forum rejecting too many posts in a short timespan. It's an anti-spam measure.
 
Last edited by a moderator:
Please examine and run this tiny program which illustrates what I've been trying to say.
C:
#include <stdio.h>
void get_user_input(double* start_vol)
{
    printf("\nEnter Pot liquid volume (gal): ");
    scanf("%lf", start_vol);
}
void main()
{
    double start_vol = 100.0;
    get_user_input(&start_vol);
    printf("You entered %lf\n", start_vol);
}
 
It's starting to gel. What I lack in quick I make up for in obstinate 😉

I will of course follow your code advice and take the rest of it to heart. May not be available tomorrow but the resolution is at the front of my mind. Thanks for persistence.

Your comment about legacy code reminds me of a book I read a few years back. Toyota brakes, air traffic control, runaway stock trading triggers... all consequences of such code. Enjoyable, insightful... and scary.

Be back soon. Thank you.

Overcomplicated: Technology at the Limits of Comprehension​

by Samuel Arbesman
 
I get it now!
Warnings gone of course but more importantly I have a clearer understanding of pointer concept. Still think they are they're own special kind of weird but I'm absolutely delighted with this learning and outcome.

Older but wiser today. And that's what makes older worth it. Thank you so much for all of the above replies.

Don
 

Buy us a coffee!

Buy me a coffee.
Back
Top Bottom