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

ACCESS_ONCE()

ACCESS_ONCE()

Posted Aug 13, 2012 9:38 UTC (Mon) by etienne (guest, #25256)
In reply to: ACCESS_ONCE() by daglwn
Parent article: ACCESS_ONCE()

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);
}


(Log in to post comments)

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