NO

Author Topic: warning #2046  (Read 532 times)

Offline John Z

  • Member
  • *
  • Posts: 447
warning #2046
« on: June 11, 2022, 06:05:50 pm »
In Pelles C version 11 a lot of attention was given to 'Expressions with no effect.'
such as in
RetVal = fwrite(temp2, 1, 5, p_ini);
where RetVal is never used.  It is understandable why save it if it is never used.

My question is a similar situation such as
RetVal = WritePrivateProfileStringW(....);  or ans = MessageBoxW(gHWND...);
do not raise the same warning when RetVal, or ans are not used.

Done that way on purpose?

John Z

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1927
Re: warning #2046
« Reply #1 on: June 12, 2022, 12:14:21 am »
I don't think that the code:
Code: [Select]
RetVal = fwrite(temp2, 1, 5, p_ini);cause the warning "Expressions with no effect.", even if RetVal is not used.
This because a call to a function can cause side effects that can't be traced by the compiler, so a no-effect condition can't be detected.
For the same reason you don't get any warning for the other code samples you reported.
Probably the warning is triggered elsewhere.
Try to produce a minimal example that shows the problem and post it so we can analyze it together.
« Last Edit: June 12, 2022, 12:16:16 am by frankie »

Offline John Z

  • Member
  • *
  • Posts: 447
Re: warning #2046
« Reply #2 on: June 12, 2022, 12:00:50 pm »
Thanks Frankie,

Here is an example attached.  It demonstrates my question regarding #2046, at least the first part.

Here is a deconstructed ;D example. 
In creating it I found there may be a bit more to the issue, as you suggested, but it still does what I suggested.
Just compile to see the  #2046 warnings.

There are 4 tiny procedures named Warning_Check1-4
Warning_Check1 and Warning_Check2 show the #2046 warning moving when using or not using the return value, and when used there is no warning generated.

Warning_Check3 shows the error on both statements when not using the return value from either

Warning_Check4 is an interesting complication because here I just change the return variable declaration type and then there are no warnings when the return is not used.

So perhaps the warning should be that the return value may be larger than the store variable declaration, but then why does using it eliminate the error message?

Building main.obj.
C:\Program Files\PellesC\Files\Hello_World\main.c(143): warning #2046: Expression with no effect removed.
C:\Program Files\PellesC\Files\Hello_World\main.c(161): warning #2046: Expression with no effect removed.
C:\Program Files\PellesC\Files\Hello_World\main.c(181): warning #2046: Expression with no effect removed.
C:\Program Files\PellesC\Files\Hello_World\main.c(183): warning #2046: Expression with no effect removed.
Done.

John Z

"You learn more from your mistakes than from your successes."

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1927
Re: warning #2046
« Reply #3 on: June 12, 2022, 03:49:41 pm »
I made a check, and can definitely conclude that the warning is related to type conversion, not to the unused value.
The warning description is really confusing, leading the user to wrong assumptions. Which expression with 'no-effect' is removed? The type conversion!.
The last is then coded only, and if only, the result value is used elsewhere.
To explain also the case reported by John:
Quote
My question is a similar situation such as
RetVal = WritePrivateProfileStringW(....);  or ans = MessageBoxW(gHWND...);
do not raise the same warning when RetVal, or ans are not used.
Try this snippet:
Code: [Select]
// This will not generate warning because the type of variable is the same as returned
// value, so no conversion is required
void Warning_Check5(HWND hwnd)
{
BOOL RetVal;
int ans;

RetVal = WritePrivateProfileStringW(NULL, NULL, NULL, NULL);
ans = MessageBoxW(hwnd, NULL, NULL, 0);
}
Then this one:
Code: [Select]
// This will generate the warning because type conversion is required
void Warning_Check6(HWND hwnd)
{
unsigned RetVal;
unsigned ans;

RetVal = WritePrivateProfileStringW(NULL, NULL, NULL, NULL);
ans = MessageBoxW(hwnd, NULL, NULL, 0);
}

Offline John Z

  • Member
  • *
  • Posts: 447
Re: warning #2046
« Reply #4 on: June 12, 2022, 05:26:46 pm »
Thanks frankie - Excellent clarification/explanation  AS USUAL  :)

When I saw the results from trying size_t it seemed to be related but I could not fathom why there was no error
report in the other cases where  the value was subsequently 'used.'  Clear now. thumbs up!
 
Maybe an opportunity for Pelles V12.

John Z

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1927
Re: warning #2046
« Reply #5 on: June 12, 2022, 06:24:09 pm »
Thanks John.
For the sake of precision the message is confusing because it leads the user to think that the whole expression, included the function calls, are removed (not executed).
But this would be uncompliant with the standard because could lead to make ineffective all the eventual side effects of the uncalled functions, that instead are, compliantly, executed anyway.
Different is the case of expressions without function calls, that can be removed completely, unless they induce side effects too.
I.e.
Code: [Select]
int a = b + c;    //If 'a' is never used should warn, and whole expression is not coded
If we introduce a side effect with an auto-increment:
I.e.
Code: [Select]
int a = ++b + c;    //If 'a' is never used should warn, and the expression not coded, but the auto increment is coded anyway
With this second case, if we use the variable 'c' we will get it incremented by 1 anyway. If we don't use 'c' the whole expression will be discarded.
The compiler seems behave correctly.
« Last Edit: June 13, 2022, 01:14:33 pm by frankie »