User: Password:
|
|
Subscribe / Log in / New account

ACCESS_ONCE()

ACCESS_ONCE()

Posted Aug 10, 2012 15:35 UTC (Fri) by daglwn (guest, #65432)
In reply to: ACCESS_ONCE() by jezuch
Parent article: ACCESS_ONCE()

C compilers detect it all the time. It is a trivial analysis. Users tend to ignore the warnings, however.


(Log in to post comments)

ACCESS_ONCE()

Posted Aug 12, 2012 18:52 UTC (Sun) by Wol (guest, #4433) [Link]

Which is why, when I gave a bunch of novice programmers instruction about how to maintain code, I said "the standard is (a) always turn warnings to max and (b) always fix or otherwise understand *every* warning".

We had a bunch of warnings we couldn't get rid of, hence it didn't say "fix all warnings", but "explain it away" is just as effective, if less satisfying.

Cheers,
Wol

ACCESS_ONCE()

Posted Aug 13, 2012 8:02 UTC (Mon) by jezuch (subscriber, #52988) [Link]

> C compilers detect it all the time. It is a trivial analysis. Users tend to ignore the warnings, however.

It is. And they do. And every time I see someone fixing a "use of undefined variable" warning by initializing it to zero at declaration point, I cringe. I've seen it in stable updates to the kernel a lot...

ACCESS_ONCE()

Posted Aug 13, 2012 16:31 UTC (Mon) by daglwn (guest, #65432) [Link]

Absolutely. One needs to first understand _why_ the warning is there before fixing it. Warnings don't replace understanding.

ACCESS_ONCE()

Posted Aug 13, 2012 9:38 UTC (Mon) by etienne (guest, #25256) [Link]

It is not trivial, or even possible, to detect if a variable is only initialised and used when another variable is set to a special value.
Something like (very simplified):
extern unsigned loglevel;

void fct (void) {
int avar;
if (loglevel = 4) avar = 10;
increase_loglevel();
do_some_unrelated_stuff();
if (loglevel == 5) printf ("%d\n", avar);
}

ACCESS_ONCE()

Posted Aug 13, 2012 16:34 UTC (Mon) by daglwn (guest, #65432) [Link]

It is not trivial to get an exact and accurate answer in the general case, true, but I was assuming we were talking about the common case of locally-declared variables.

Still, even in this case the compiler could warn about it even if it doesn't know for sure. The code certainly looks suspicious and a warning would be appropriate. False positives are just fine if they are limited in number. The compiler can provide directives to suppress them if the programmer knows it's not a problem.

Note that gcc does just this. It warns that variables *might* be uninitialized.

ACCESS_ONCE()

Posted Aug 13, 2012 16:50 UTC (Mon) by nybble41 (subscriber, #55106) [Link]

Fortunately, in your example avar is always initialized to 10. :)

Assuming "loglevel = 4" was replaced with "loglevel == 4", I would expect the compiler to generate a warning in this case, since it can't _prove_ that avar was initialized before the printf() call. I would also hope that the compiler would take advantage of the fact that avar is either 10 or undefined to simply set it to 10 regardless of loglevel, for code size and performance reasons if nothing else.

In cases like this, IMHO, it would be better to use a common flag rather than testing loglevel multiple times:

void fct (void) {
int avar;
bool use_avar;
use_avar = (loglevel == 4);
if (use_avar) avar = 10;
increase_loglevel();
do_some_unrelated_stuff();
if (use_avar) printf ("%d\n", avar);
}

I'm not sure whether the compiler can follow this any better than before, so there may still be a warning, but at least the coupling is visible to anyone reading the code, and doesn't depend on the implementation of external functions.


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds