ques 1.34 c-faq

S

SAHIL MAHLA

Hi Experts,

Could you explain what does they mean by "The implicit external function declaration that can occur when a function is called does not help when a function name's only use is for its value." -in ques 1.34 C-faq

Thanks in advance!!!
 
K

Kaz Kylheku

Hi Experts,

Hi Sahil,

I'm glad you're reading the FAQ.
Could you explain what does they mean by "The implicit external function
declaration that can occur when a function is called does not help when a
function name's only use is for its value." -in ques 1.34 C-faq

An external function declaration is a function declaration which has
external linkage:

static int foo(void); /* internal declaration */

int bar(void); /* external declaration */

An implicit declaration occurs when your program contains the syntax
of a function call, but whose identifier isn't declared anywhere.

For instance, suppose that a declaration for foo hasn't been
seen previously, and we have this:

int x = foo("abc");

in this situation, an implicit declaration is supplied: an unwritten, invisible
declaration that exists in the "mind" of the compiler, so to speak. The
language implementation proceeds on the assumption that foo is a function.
(This is very unsafe: we have no idea whether or not foo can be called with a
string argument, or whether or not it returns int.)

The FAQ question is stating somewhat clumsily that this implicit declaration
logic does not kick in if the function is only referenced to obtain the
function pointer as a value. For instance:

int (*ptr)(char *) = foo;

Here, if foo has not been declared, it will not be implicitly declared as a
function because it's not used to express a function call. This is simply a
diagnosable error: foo is an undeclared identifier.

This is the case even though the context makes it clear that foo is probably a
function pointer or a function, just like the context foo("abc").

(Some languages are deeply based on inference: programs require few
declarations, because the information propagates implicitly through the program
by logical inferences which follow the data flows.)
 
E

Eric Sosman

[...]
For instance, suppose that a declaration for foo hasn't been
seen previously, and we have this:

int x = foo("abc");

in this situation, an implicit declaration is supplied: an unwritten, invisible
declaration that exists in the "mind" of the compiler, so to speak. [...]

(Kaz knows this, but the O.P. may not): The implicit declaration
of functions mentioned in FAQ 1.34 (and described more fully in 1.25)
occurs in "prehistoric C" and in the version of C first standardized
in 1989 ("ANSI C"). However, the C standard has continued to develop
over the last quarter-century, and implicit declaration is no longer
part of the language. As of the 1999 version of the standard, all
identifiers must be declared prior to use, period.

Summary:

- Compilers for modern C will produce error messages if you
try to use a function without declaring it,

- Compilers for old versions of C (or a modern compiler
that you've told to behave like an older one) will do as
Kaz and the FAQ describe, and

- Even with an older compiler it's questionable practice to
rely on implicit declarations. Declare what you use; it's
safer in the long run.
 
B

BartC

Eric Sosman said:
On 3/12/2014 12:05 AM, Kaz Kylheku wrote:
int x = foo("abc");

in this situation, an implicit declaration is supplied: an unwritten,
invisible
declaration that exists in the "mind" of the compiler, so to speak.
[...]

(Kaz knows this, but the O.P. may not): The implicit declaration
of functions mentioned in FAQ 1.34 (and described more fully in 1.25)
occurs in "prehistoric C" and in the version of C first standardized
in 1989 ("ANSI C"). However, the C standard has continued to develop
over the last quarter-century, and implicit declaration is no longer
part of the language. As of the 1999 version of the standard, all
identifiers must be declared prior to use, period.

Summary:

- Compilers for modern C will produce error messages if you
try to use a function without declaring it,

- Compilers for old versions of C (or a modern compiler
that you've told to behave like an older one) will do as
Kaz and the FAQ describe, and

Three x86 compilers I've tried will only give warnings if a function has not
been declared, even when (with two of them) explicitly told to use C99.
(Although I'm sure gcc has some obscure option buried in it somewhere that
will give errors instead. But an obscure one is no good to me!)

The only hard error given would be a link error later on, *if* a function of
that name doesn't exist. (If it does, but happens to be the wrong one, or
the arguments are incorrect, then there will be no error at all.)

Perhaps they could do with taking it more seriously, and to have an error as
the default rather than a warning. (Meanwhile DMC is stopping me using it
because it still thinks that assigning a string literal of signed char* to a
unsigned char* is worthy of a hard compilation error. It needs to get its
priorities right.)
 
E

Eric Sosman

Eric Sosman said:
[...]
- Compilers for modern C will produce error messages if you
try to use a function without declaring it,
[...]

Three x86 compilers I've tried will only give warnings if a function has
not been declared, even when (with two of them) explicitly told to use
C99. (Although I'm sure gcc has some obscure option buried in it
somewhere that will give errors instead. But an obscure one is no good
to me!)

The C Standard requires only that the implementation produce
a "diagnostic message," and doesn't distinguish between warnings,
errors, cautions, forebodings, ill omens, and threats. I used
the informal term "error messages" because it appears the O.P. is
very new to C and perhaps likely to be put off by Standardese.

As for the obscurity of compiler options -- well, *all* options
are obscure to someone unwilling to learn about them.
Perhaps they could do with taking it more seriously, and to have an
error as the default rather than a warning. [...]

Maybe there should be an obscure option to make the compiler
treat all warnings as errors. Why don't you suggest such a thing
to the gcc folks?
 
S

SAHIL MAHLA

I am deeply thankful to Kaz and all experts here for giving your time for my doubts.
 
K

Kaz Kylheku

[...]
For instance, suppose that a declaration for foo hasn't been
seen previously, and we have this:

int x = foo("abc");

in this situation, an implicit declaration is supplied: an unwritten, invisible
declaration that exists in the "mind" of the compiler, so to speak. [...]

(Kaz knows this, but the O.P. may not): The implicit declaration
of functions mentioned in FAQ 1.34 (and described more fully in 1.25)
occurs in "prehistoric C" and in the version of C first standardized
in 1989 ("ANSI C"). However, the C standard has continued to develop
over the last quarter-century, and implicit declaration is no longer
part of the language. As of the 1999 version of the standard, all
identifiers must be declared prior to use, period.

Summary:

- Compilers for modern C will produce error messages if you
try to use a function without declaring it,

- Compilers for old versions of C (or a modern compiler
that you've told to behave like an older one) will do as
Kaz and the FAQ describe, and


Compilers for 1990 C will also produce error messages.

$ cat test.c
int main(void)
{
foo();
}

GCC compiling as 1990 C:

$ gcc -Wall -std=c90 test.c
test.c: In function ‘main’:
test.c:3:3: warning: implicit declaration of function ‘foo’ [-Wimplicit-function-declaration]
test.c:4:1: warning: control reaches end of non-void function [-Wreturn-type]

GCC compiling as 1999 C:
$ gcc -Wall -std=c99 test.c
test.c: In function ‘main’:
test.c:3:3: warning: implicit declaration of function ‘foo’ [-Wimplicit-function-declaration]

The only difference we see here is that falling off the end of main without returning
a value is now "blessed" in 1999 C, and implicitly converted to a "return 0", so
there is no "control reaches end" warning.

When GCC is wearing its C90 hat, it's producing an extra diagnostic about implicit
functions. When GCC is wearing its C99 hat, it is producing a required diagnostic; but
only as a warning; it still provides the traditional behavior.
- Even with an older compiler it's questionable practice to
rely on implicit declarations. Declare what you use; it's
safer in the long run.

If you're using gcc, use at least these:

-Wall -Werror=implicit-function-declaration -Werror=missing-prototypes -Werror=strict-prototypes

-Werror=implicit-function-declaration causes the uses of undeclared functions to
be an error which fails compilation.

-Werror=strict-prototypes makes it a compilation-stopping error to have a function
declaration or definition that doesn't provide a prototype unless the prototype
is already established previously.

-Werror=missing-prototypes makes it a compilation-stopping error to define a function with external linkage without a prior prototype.

Why is the last one useful? For one thing, it stops you from accidentally
making internal functions external, so you make all the module private
functions static, reducing pollution of the external namespace.

More importantly, it catches the following situation:

module A:

#include "module_b.h"
...
module_b_function(42); /* prototype in scope, everything looks cool! */


module B:

/* Ooops, module B neglects to include its own module_b.h ! */

void module_b_function(char *str) { ... } /* does not match prototype */
 
J

James Kuyper

On 03/12/2014 09:23 AM, Eric Sosman wrote:
....
part of the language. As of the 1999 version of the standard, all
identifiers must be declared prior to use, period.

Summary: ....
- Even with an older compiler it's questionable practice to
rely on implicit declarations. Declare what you use; it's
safer in the long run.

In my opinion, "questionable" not nearly strong enough. Any code that
relies upon implicit declarations is defective code by my book, and
would never pass a code review, and I reached that conclusion not long
after first learning C, long before the C90 standard came out. The fact
that a great many other people felt the same way, is the reason why
implicit declarations were finally dropped in C99.
 
E

Eric Sosman

On 03/12/2014 09:23 AM, Eric Sosman wrote:
...

In my opinion, "questionable" not nearly strong enough. Any code that
relies upon implicit declarations is defective code by my book, and
would never pass a code review, and I reached that conclusion not long
after first learning C, long before the C90 standard came out. The fact
that a great many other people felt the same way, is the reason why
implicit declarations were finally dropped in C99.

We're in agreement, at least as far as new code goes. But I
wouldn't go back over a large body of old existing code merely to
insert function declarations; rather, I'd continue to build it
with "-std=ansi" or the like.

If other reasons to modernize the old code arose, then sure:
Forty maids with forty mops, and we're going through a full test
cycle all over again. But I wouldn't summon the mops and maids
without those other reasons.
 
K

Kenny McCormack

On 03/12/2014 09:23 AM, Eric Sosman wrote:
...

In my opinion, "questionable" not nearly strong enough. Any code that

Great! A war between two CLC regs - trying to out-pedant each other.
 
J

James Kuyper

On 3/12/2014 11:45 AM, James Kuyper wrote: ....

We're in agreement, at least as far as new code goes. But I
wouldn't go back over a large body of old existing code merely to
insert function declarations; rather, I'd continue to build it
with "-std=ansi" or the like.

I have taken moderate-sized bodies of code, and added function
prototypes in all applicable places. Whenever I've done so, I have
invariably uncovered defects in the unmodified code that were hidden by
the implicit declarations. I'm not talking about things that only became
defects because of the new rules in C90 or C99; I'm talking about things
that were defects even according to the rules of K&R C, but which
remained hidden due to the fact that there was no way to validate the types.

I can understand the temptation to not bother modifying sufficiently
large bodies of code, but I think it would be worth-while doing so.
If other reasons to modernize the old code arose, then sure:
Forty maids with forty mops, and we're going through a full test
cycle all over again. But I wouldn't summon the mops and maids
without those other reasons.

I would, but I've worked for many bosses who wouldn't have given me
permission to do so. I have one body of code that I've been responsible
for maintaining since 1996, but I'm still working under rules that
grandfather old modules: I'm not allowed to modify them in any way
unless I have to in order to fix a bug or add a feature. There are still
a few modules in that body of code that I've never been authorized to
bring up to standard.
 
D

David Brown

Eric Sosman said:
[...]
- Compilers for modern C will produce error messages if you
try to use a function without declaring it,
[...]

Three x86 compilers I've tried will only give warnings if a function has
not been declared, even when (with two of them) explicitly told to use
C99. (Although I'm sure gcc has some obscure option buried in it
somewhere that will give errors instead. But an obscure one is no good
to me!)

The C Standard requires only that the implementation produce
a "diagnostic message," and doesn't distinguish between warnings,
errors, cautions, forebodings, ill omens, and threats. I used
the informal term "error messages" because it appears the O.P. is
very new to C and perhaps likely to be put off by Standardese.

As for the obscurity of compiler options -- well, *all* options
are obscure to someone unwilling to learn about them.
Perhaps they could do with taking it more seriously, and to have an
error as the default rather than a warning. [...]

Maybe there should be an obscure option to make the compiler
treat all warnings as errors. Why don't you suggest such a thing
to the gcc folks?

That would be "-Werror". Whether it is obscure or not is a matter of
opinion, of course.
 
K

Kenny McCormack

Maybe there should be an obscure option to make the compiler
treat all warnings as errors. Why don't you suggest such a thing
to the gcc folks?

That would be "-Werror". Whether it is obscure or not is a matter of
opinion, of course.[/QUOTE]

No, you missed the point. Everybody knows about -Werror. It's not obscure
at all.

We were talking about the need for an *obscure* option...

Many of us are scheduled to meet with the gcc folks on this next week.
 
K

Kaz Kylheku

That would be "-Werror". Whether it is obscure or not is a matter of
opinion, of course.

No, you missed the point. Everybody knows about -Werror. It's not obscure
at all.

We were talking about the need for an *obscure* option...[/QUOTE]

There is one: -Werror=<name-of-specific-warning>.

Much, much more useful than -Werror. You can fully customize what the
compiler brakes for.
 
B

BartC

Kaz Kylheku said:
There is one: -Werror=<name-of-specific-warning>.

Much, much more useful than -Werror.

But, for gcc you first need to use the -std=c99 option (not -std:c99
nor -std=C99 nor -std:C99 nor -C99; or even --std:c99 etc).

Then you have to use -Werror, preferably with the option of the specific
warning, when you can find out what it is! (There were some 1200 gcc options
last time I looked, described in an 800-page document. It's a monster.)

And if you want to compile the same code with a different compiler, then you
have to start over again.

I'm just saying that undeclared names should be reported as errors as a
matter of course, with the options instead being used to turn the error into
a warning. (And here the obscurity of the options is actually helpful in
encouraging people to fix the problem instead!)

(Fortunately, since I pre-process most of my input to C compilers anyway,
I'm in the process of taking over most of these checks myself. Then I'll be
a lot less dependent on these various compiler foibles.

The amount of stuff I could leave undefined or get wrong, and yet not
generate an error until much later, if at all, was becoming a joke. Yet
leave out one semicolon and the compiler is on top of it like a ton of
bricks!)
 
B

Ben Bacarisse

BartC said:
But, for gcc you first need to use the -std=c99 option (not -std:c99
nor -std=C99 nor -std:C99 nor -C99; or even --std:c99 etc).

With some of your posts I get the feeling that we must work in very
different ways. Sure, it's a plain that options can't be guessed, but
that's inevitable. But it's also inevitable that you'll want read up
about the option to see what it does, so you don't really gain much my
making the option syntax very flexible. Once I've found the option, it
goes into a make file, or a build script or some such thing, so I don't
have to keep remembering how to type it.
Then you have to use -Werror, preferably with the option of the specific
warning, when you can find out what it is! (There were some 1200 gcc options
last time I looked, described in an 800-page document. It's a
monster.)

Here, gcc helpfully tells me the name of the option (when it is
individually controllable):

t.c:8:6: warning: implicit declaration of function ‘f’
[-Wimplicit-function-declaration]

and if, later on, you find that clutters up your error messages too much
you can turn it off with -fno-diagnostics-show-option.
And if you want to compile the same code with a different compiler, then you
have to start over again.

clang, very much a different compiler, tries to be cli-compatible with
gcc. The examples here certainly carry over to clang with no change at
all. Just as soon as every other compiler decides to use gcc's options
(and option syntax) you will never have these problems again!
I'm just saying that undeclared names should be reported as errors as
a matter of course, with the options instead being used to turn the
error into a warning.

That would be my preference too, but since I can get exactly that
behaviour with for what seems to me to be very little effort, I would
find it hard to summon up the ire to complain about it.

<snip>
 
B

BartC

clang, very much a different compiler, tries to be cli-compatible with
gcc. The examples here certainly carry over to clang with no change at
all. Just as soon as every other compiler decides to use gcc's options
(and option syntax) you will never have these problems again!

Aargh! I hope not!

I like things to become simpler not more complicated. It was a joy recently,
after a couple of years using gcc, to try out lccwin32 again and see it
whizz through my sources. And any messages were simple, compact and
understandable. (It also reported undeclared functions without being told!)

(I've just looked at clang, with a view to trying it out, but it seems to be
one of those apps only available in source form. It also seems to be part of
llvm, which, last time I checked it out, was an even more ginormous project
than gcc. (I counted 44 /sets/ of documentation for it!

I will make the promise that, if and when I release some sizeable project of
mine and it has to be in source form, it will be as simple to compile as a
Hello, World program.)
 
D

David Brown

Aargh! I hope not!

gcc is the nearest we have to a defacto standard in compiler extensions,
command line options, and inline assembly syntax. Other compiler
vendors either go their own way, or copy from gcc - and the more that
copy from gcc, the simpler things will be for all who use or support
multiple compilers. (Of course, just because I claim gcc is the
/nearest/ we have to a standard, does not mean it is /close/ to being a
standard.)
I like things to become simpler not more complicated. It was a joy
recently, after a couple of years using gcc, to try out lccwin32
again and see it whizz through my sources. And any messages were
simple, compact and understandable. (It also reported undeclared
functions without being told!)

(I've just looked at clang, with a view to trying it out, but it
seems to be one of those apps only available in source form. It also
seems to be part of llvm, which, last time I checked it out, was an
even more ginormous project than gcc. (I counted 44 /sets/ of
documentation for it!

apt-get install clang
yum install clang
<http://lmgtfy.com/?q=clang+windows+binaries&l=1>
<http://llvm.org/releases/download.html>


Of course llvm has lots of documentation - it is not a toy windows-only
c-only x86-only closed-source compiler. It is a major project,
supporting a number of target processors (not nearly as many as gcc, but
still quite a few), several compiled programming languages, multiple JIT
compiled languages, and a wide range of tools that are related to
program language interpretation and analysis. And as the aim is for
lots of people to use it for development of their own tools, the llvm
documentation is for people who write compilers - not just people who
use them.
 
B

BartC

Just as soon as every other compiler decides to use
Other compiler
vendors either go their own way, or copy from gcc - and the more that
copy from gcc, the simpler things will be for all who use or support
multiple compilers.

I handle each compiler separately in my IDE, it's not that big a problem,
once it's set up. But finding your way around gcc in the first place is
still a problem. (And, once you forget about it for a while, you have to
learn again when something else comes up.)

Thanks. I don't know where I ended up with my search, but it said nothing
about binaries nor even downloads.

But, it's quite a hefty compiler! (28MB just for the main executable.)

And I see what you mean about having a gcc-compatible interface: you compile
hello.c and up with the output in a.out. Very useful in Windows! And you say
it would be better if all compilers did this...
 
K

Ken Brody

Thanks. I don't know where I ended up with my search, but it said nothing
about binaries nor even downloads.

But, it's quite a hefty compiler! (28MB just for the main executable.)
[...]

The Visual Studio 2012 installation on my Windows box is 3GB. (The C
compiler [okay, C and C++ compiler] binaries alone are 85MB.)
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top