what's meaning of this ?

T

Tommy

struct stat *stats IF_LINT (= 0);

I don't know why "IF_LINT (= 0)" is needed ?

Source is df.c of df program on Linux coreutils-5.2.1\coreutils-5.2.1\src

Thanks!
 
V

vippstar

struct stat *stats IF_LINT (= 0);

I don't know why "IF_LINT (= 0)" is needed ?

Syntax error, constraint violation that requires a diagnostic message.
Source is df.c of df program on Linux coreutils-5.2.1\coreutils-5.2.1\src

Thanks!

ask some more relevant newsgroup then. comp.lang.c discusses ANSI/ISO
C.
 
J

James Kuyper

Syntax error, constraint violation that requires a diagnostic message.

Even if preceeded by a suitable definition of a function-like macro
named IF_LINT()? It is a very common convention that identifiers in
all-caps are generally macros, so that's something you should at least
have thought about.
 
R

Richard Tobin

struct stat *stats IF_LINT (= 0);

I don't know why "IF_LINT (= 0)" is needed ?

Presumably it's a macro that expands to "= 0" if you're using lint (a
C checker) and nothing otherwise. And presumably this is because lint
wrongly complains about the variable being uninitialised otherwise.

-- Richard
 
K

Keith Thompson

pete said:
IF_LINT appears to be a function like macro.

The answer to your question is: "What is IF_LINT?"

My first guess is that under a certain circumstance,
perhaps if lint is being used,
the object is initialized upon declaration.

That's my conclusion as well. Searching the coreutils source tree for
"IF_LINT" would probably tell you something useful.

Further speculation: the line expands to
struct stat *status;
if lint is *not* being used, and to
struct stat *status = 0;

if lint *is* being used. (lint is a program, separate from the
compiler, that analyzes source code for possible problems but doesn't
generate code; there are numerous versions.) Probably lint complains
that status might be used before it's set if the initialization isn't
there. Probably the author is sufficiently confident that it *isn't*
used before being set that he prefers to omit the initialization for
actual compilation. Possibly he uses something like valgrind to
verify at execution time that status is never actually used before
being set, and the initialization would prevent valgrind from
detecting a problem.

(If the author *isn't* using something like valgrind, then omitting
the initialization only when not using lint would be IMHO a foolish
microoptimization.)
 
R

Richard Tobin

Presumably it's a macro that expands to "= 0" if you're using lint (a
C checker) and nothing otherwise. And presumably this is because lint
wrongly complains about the variable being uninitialised otherwise.
[/QUOTE]
s/wrongly/rightly/

It's certainly true that "struct stat *stats" does not initialise the
variable. But I didn't say lint was wrong about the variable being
uninitialised, I said it was wrong to complain. Whether it's right to
complain about this depends on the rest of the program, and since the
author used the macro we can assume that it's wrong.

-- Richard
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:

Um, my point was only that the complaint is accurate - the variable /is/
uninitialised (if we have glarked IF_LINT correctly, which seems likely).

Whether the complaint is justified is another matter. But it is certainly
correct.

We can't know whether the complaint is correct without knowing what
the complaint is.

It could be something along the lines of

Variable "stats" may be used before being initialized

And it could be that, due to circumstances beyond lint's ability to
analyze, "stats" actually cannot ever be used before it's initialized.

I doubt that lint would complain just because a variable declaration
doesn't include an initializer. For example, lint probably wouldn't
complain about something like this:

int x;
x = 42;
printf("x = %d\n", x);

In my hypothetical scenario, the ``= 0'' is necessary to inhibit a
spurious warning from lint, and removing the ``= 0'' is necessary to
allow another tool, perhaps something like valgrind, to confirm that
the warning is in fact spurious.

An alternative might be to restructure the code so that it's obvious,
even to lint, that stats is never actually used before it's
initialized. It's possible that such restructuring would result in
clearer, simpler, and all-around better code. But without actually
looking at the code in question, it's impossible to be sure.
 
I

Ian Collins

Richard said:
Keith Thompson said:


Um, my point was only that the complaint is accurate - the variable /is/
uninitialised (if we have glarked IF_LINT correctly, which seems likely).

Whether the complaint is justified is another matter. But it is certainly
correct.
Evolve to C99 and the point (almost) becomes moot.
 
K

Keith Thompson

Ian Collins said:
Evolve to C99 and the point (almost) becomes moot.

That's a bit vague. Are you suggesting that C99's permission to mix
declarations and statements makes it easier to declare stats later and
initialize it at the point of declaration?

A quick glance at the actual source code suggests that it might not be
that simple. The first assignment to stats is inside an if statement;
the first use of it is inside a later if statement.
 
I

Ian Collins

Keith said:
That's a bit vague. Are you suggesting that C99's permission to mix
declarations and statements makes it easier to declare stats later and
initialize it at the point of declaration?
In many cases, yes. This example wasn't a good one, but in general
introducing variables where they are required and can be meaningfully
initialised disposes of the should we/shouldn't we initialise variables
when they are declared argument.

I'm still surprised to find variables that are only used in a restricted
scope (say a loop) declared at the top of a function in C89 code. I
could never understand why people do this. What makes the situation
worse is this often happens in ridiculously long functions. I guess
these are both signs of poor coding practice.
 
S

Serve Lau

s/wrongly/rightly/

It's certainly true that "struct stat *stats" does not initialise the
variable. But I didn't say lint was wrong about the variable being
uninitialised, I said it was wrong to complain. Whether it's right to
complain about this depends on the rest of the program, and since the
author used the macro we can assume that it's wrong.[/QUOTE]

Stuff like this is always debatable when it comes to code checkers.
Doing a technically useless initialization might seem odd but always
initializing variables could improve your code quality.

Say you have this code.

struct stat *foo(int x) {
struct stat *stats;

if (x<3)
stats = &stat1;
else
stats = &stat2;

return stats;
}

lint might complain that stats may not be initialized which would be wrong
so you refuse to initialize it to 0.
Then later the code changes to

struct stat *void foo(int x) {
struct stat *stats;

if (x<3)
stats = &stat1;
else if (x < 6)
stats = &stat2;

return stats;
}

then suddenly the code calling foo which even checks for NULL crashes. So in
a way when listening to lint in this case could improve code quality
 
S

santosh

Ian said:
In many cases, yes. This example wasn't a good one, but in general
introducing variables where they are required and can be meaningfully
initialised disposes of the should we/shouldn't we initialise
variables when they are declared argument.

I'm still surprised to find variables that are only used in a
restricted scope (say a loop) declared at the top of a function in C89
code. I could never understand why people do this.

Because mixed code and declarations was disallowed in C89/C90?

Personally I find mixed code and declarations a convenient feature, and
it does reduce the unwanted scope of variables *and* puts them close to
their point of use in code, but OTOH, it tends to scatter variables
through code, which I find aesthetically less pleasing than having them
collected in one place.

This feature of C99 is not very useful for short functions, but despite
the maxims of good s/w engineering, occasionally, some functions do
tend to grow rather big, and then mixed code declarations do prove
nifty. In any case I tend to place my variable declarations at the
start of the nearest enclosing block to their place of usage or at the
function beginning if they are used at most places in the function.
This is better than placing them all at the start of the function and
yet is legal in C89/C90 as well as C99. I admit that the new iteration
statements scope is sorely tempting to use though.
 
R

Richard Tobin

Serve Lau said:
Stuff like this is always debatable when it comes to code checkers.
Doing a technically useless initialization might seem odd but always
initializing variables could improve your code quality.

At the risk of flogging a dead horse, I think it has the opposite
effect.
Then later the code changes to

struct stat *void foo(int x) {
struct stat *stats;

if (x<3)
stats = &stat1;
else if (x < 6)
stats = &stat2;

return stats;
}

then suddenly the code calling foo which even checks for NULL crashes. So in
a way when listening to lint in this case could improve code quality

Any reasonable compiler will warn that stats may be used uninitialised
here. Initialising it to NULL will suppress that warning.

-- Richard
 
R

Richard Tobin

Initialising it to NULL will suppress that warning.
[/QUOTE]
What warning? The Standard does *not* require implementations to diagnose
the use of indeterminate values.

Nor does it require dereferencing a NULL pointer to do anything
noticable. The question is what is most likely to reveal errors in
practice.

-- Richard
 
B

Ben Bacarisse

Richard Heathfield said:
Richard Tobin said:

Perhaps - but not only is there no imposition on conforming implementations
to be reasonable, but even reasonable compilers will fail to report this
on occasion.

Consider foo.c, below:

#include <stdio.h>
#include <math.h>

struct foo_
{
double x;
double y;
double r;
};
typedef struct foo_ foo;

void foocalc(foo *p)
{
p->r = sqrt(p->x * p->x + p->y * p->y);
}

int main(void)
{
foo f;
f.x = 3.14;
foocalc(&f);
printf("%.6f\n", f.r);
return 0;
}

me@here:~/scratch> make
gcc -W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wbad-function-cast -Wmissing-prototypes
-Wstrict-prototypes -Wmissing-declarations -Winline -Wundef
-Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings
-ffloat-store -O2 -fno-builtin -g -pg -c -o foo.o foo.c
foo.c:13: warning: no previous prototype for `foocalc'
gcc -W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wbad-function-cast -Wmissing-prototypes
-Wstrict-prototypes -Wmissing-declarations -Winline -Wundef
-Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings
-ffloat-store -O2 -fno-builtin -g -pg -o foo foo.o -lm -lncurses -lpcl
me@here:~/scratch>

Note the complete absence of any diagnostic message regarding the use of
uninitialised f.y.

The preference often reflects the tools one uses. Given the above,
valgrind reports:

==26364== Conditional jump or move depends on uninitialised value(s)
==26364== at 0x8048447: foocalc (foo.c:14)
==26364== by 0x804848E: main (foo.c:21)

I find valgrind too useful to handicap by initialising everything
since it can find a bug caused by use of an indeterminate value before
you even get to inspect the program results. I spent a lot of time
finding bugs in other people's code and a report like the one above is
more useful than trying to find the incorrect result in maze of
mysterious output.
 
J

James Kuyper

santosh said:
Ian Collins wrote: ....

Because mixed code and declarations was disallowed in C89/C90?

He wasn't talking about mixed code and declarations. He was talking
about defining variables in blocks other than function blocks, which was
certainly allowed in C89, and I believe it was allowed much earlier than
that.
Personally I find mixed code and declarations a convenient feature, and
it does reduce the unwanted scope of variables *and* puts them close to
their point of use in code, but OTOH, it tends to scatter variables
through code, which I find aesthetically less pleasing than having them
collected in one place.

I find that the closer the definition of a variable is to the place
where it is used, the less confusing it is.

....
nifty. In any case I tend to place my variable declarations at the
start of the nearest enclosing block to their place of usage or at the

That IS what he was talking about above.
 
A

Andrew

Ben Bacarisse said:


True, but it is also true that the tools one has available on site are not
always the tools one would like to have available.

<snip>

Well, if you're writing code on a site where your allowed toolset is
restricted, hopefully your coding style is also restricted - to one
that is reasonable given the type of debugging you are able to do.
 
K

Keith Thompson

Richard Heathfield said:
Ben Bacarisse said:

True, but it is also true that the tools one has available on site are not
always the tools one would like to have available.

<snip>

Is valgrind unavailable to you?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top