Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Can a static function declaration conflict with a non-static declaration?

Reply
Thread Tools

Can a static function declaration conflict with a non-static declaration?

 
 
nospam_timur@tabi.org
Guest
Posts: n/a
 
      12-12-2006
Let's say I have two files, myfile.h and myfile.c:

myfile.h:

int myfunction(int x);

myfile.c:

#include "myfile.h"

static int myfunction(char *x)
{
return 0;
}

Does this conform to the C standard? With GCC 4, this generates an
error, because the definitions of myfunction() conflict. I have a
colleague who says this compiles in GCC 3, because the static version
of myfunction() overrides the non-static prototype from the header
file. I believe that GCC 3 is just ignoring the problem, and that it's
technically a bug, but I can't find any documentation that specifically
says that static and non-static declarations of the same function have
to have the same parameters and return type.

 
Reply With Quote
 
 
 
 
Chris Torek
Guest
Posts: n/a
 
      12-12-2006
In article <(E-Mail Removed) .com>
http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote:
>Let's say I have two files, myfile.h and myfile.c:
>
>myfile.h:
>
>int myfunction(int x);
>
>myfile.c:
>
>#include "myfile.h"
>
>static int myfunction(char *x)
>{
> return 0;
>}
>
>Does this conform to the C standard?


6.1.2.2 Linkages of identifiers
[snippage]
[#7] If, within a translation unit, the same identifier
appears with both internal and external linkage, the
behavior is undefined.

The first declaration, in myfile.h (first because it is #include-d
before the second declaration) does not use the "extern" keyword and
has no previous declaration in scope, so it specifies external linkage
for the identifier "myfunction".

The second declaration, using the "static" keyword, specifies internal
linkage for the identifier "myfunction".

The behavior is undefined.

>With GCC 4, this generates an error, because the definitions of
>myfunction() conflict.


Allowed, since the behavior is undefined.

>I have a colleague who says this compiles in GCC 3, because the
>static version of myfunction() overrides the non-static prototype
>from the header file.


Also allowed, since the behavior is undefined.

GCC 4's complaint is probably a good idea, since relying on undefined
behavior when "well-defined behavior" is at least as good is unwise.
(Using undefined behavior for positive benefit, in places where
"well-defined behavior" is no good, is another matter entirely.
That is, I would not call it "unwise" to "#include <graphics.h>"
in order to draw graphics on a screen or window. The cost --
behavior undefined by a widespread standard -- is outweighed by
the benefit of being able to do what the code is required to do.
But here there is no benefit from mixing internal and external
linkage, only a cost.)

>I believe that GCC 3 is just ignoring the problem, and that it's
>technically a bug, but I can't find any documentation that specifically
>says that static and non-static declarations of the same function have
>to have the same parameters and return type.


Since the behavior is undefined, anything can happen.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      12-12-2006
Chris Torek <(E-Mail Removed)> writes:

> In article <(E-Mail Removed) .com>
> (E-Mail Removed) <(E-Mail Removed)> wrote:
>>Let's say I have two files, myfile.h and myfile.c:
>>
>>myfile.h:
>>
>>int myfunction(int x);
>>
>>myfile.c:
>>
>>#include "myfile.h"
>>
>>static int myfunction(char *x)
>>{
>> return 0;
>>}
>>
>>Does this conform to the C standard?

>
> 6.1.2.2 Linkages of identifiers
> [snippage]
> [#7] If, within a translation unit, the same identifier
> appears with both internal and external linkage, the
> behavior is undefined.
>
> The first declaration, in myfile.h (first because it is #include-d
> before the second declaration) does not use the "extern" keyword and
> has no previous declaration in scope, so it specifies external linkage
> for the identifier "myfunction".
>
> The second declaration, using the "static" keyword, specifies internal
> linkage for the identifier "myfunction".
>
> The behavior is undefined.


I agree.

However, it may be worth adding that the opposite situation,
shown below, is OK:

static int myfunction(void);
int myfunction(void) {
...
}

This is because there is an explicit exception for this situation
in the Standard:

For an identifier declared with the storage-class specifier
extern in a scope in which a prior declaration of that
identifier is visible,23) if the prior declaration specifies
internal or external linkage, the linkage of the identifier
at the later declaration is the same as the linkage
specified at the prior declaration. If no prior declaration
is visible, or if the prior declaration specifies no
linkage, then the identifier has external linkage.

--
Just another C hacker.
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      12-12-2006
In article <(E-Mail Removed)>
Ben Pfaff <(E-Mail Removed)> wrote (in part):
>... it may be worth adding that the opposite situation,
>shown below, is OK:
>
> static int myfunction(void);
> int myfunction(void) {
> ...
> }
>
>This is because there is an explicit exception for this situation
>in the Standard:
>
> For an identifier declared with the storage-class specifier
> extern in a scope in which a prior declaration of that
> identifier is visible,23) if the prior declaration specifies
> internal or external linkage, the linkage of the identifier
> at the later declaration is the same as the linkage
> specified at the prior declaration. If no prior declaration
> is visible, or if the prior declaration specifies no
> linkage, then the identifier has external linkage.


The exception quoted here is specific to declarations using the
"extern" keyword. So, this means:

static int myfunction(void);
extern int myfunction(void) {
...
}

is OK. So is:

static double d;
extern double d;

In these two cases, the "extern" keyword functions the same as the
"static" keyword, giving the identifier internal linkage.

Omitting the "extern" keyword entirely is even more bizarre:

[#5] If the declaration of an identifier for a function has
no storage-class specifier, its linkage is determined
exactly as if it were declared with the storage-class
specifier extern. If the declaration of an identifier for
an object has file scope and no storage-class specifier, its
linkage is external.

Note the different specifications for functions vs objects. This
means Ben Pfaff's example (a function) is OK: with no storage class
specifier keyword, the function inherits the linkage of the visible
prior declaration (i.e., the "static" one right above it) -- but
my example with "d" above becomes invalid if the "extern" keyword
is removed:

static double d;
double d; /* ERROR */

I have no idea why this particular (apparently entirely gratuitous)
inconsistency exists in the C standards.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      12-12-2006
In article <(E-Mail Removed)>,
Chris Torek <(E-Mail Removed)> wrote:

>Omitting the "extern" keyword entirely is even more bizarre:
>
> [#5] If the declaration of an identifier for a function has
> no storage-class specifier, its linkage is determined
> exactly as if it were declared with the storage-class
> specifier extern. If the declaration of an identifier for
> an object has file scope and no storage-class specifier, its
> linkage is external.
>
>Note the different specifications for functions vs objects. This
>means Ben Pfaff's example (a function) is OK: with no storage class
>specifier keyword, the function inherits the linkage of the visible
>prior declaration (i.e., the "static" one right above it) -- but
>my example with "d" above becomes invalid if the "extern" keyword
>is removed:
>
> static double d;
> double d; /* ERROR */
>
>I have no idea why this particular (apparently entirely gratuitous)
>inconsistency exists in the C standards.


Presumably it's related to the fact that

double d;

is all you need to do to cause a double to exist, but

int myfunction(void);

still leaves you in need of the definition. There's no default
initializer for functions! The only use of a function declaration
without a body is to declare the function's interface, so why require
the user to add a redundant "extern"?

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
type declaration in declaration of a parameter or return type of a function Luca Forlizzi C Programming 4 11-14-2010 09:30 PM
css conflict (or html conflict) charles cashion HTML 2 02-18-2009 09:41 PM
Variable declaration taken as a function pointer declaration Bolin C++ 4 12-02-2005 05:28 PM
conflicting declaration for iostream, namespace conflict? humble04@gmail.com C++ 2 12-29-2004 02:39 PM
Function declaration in class declaration Ovidesvideo C++ 4 12-10-2004 06:36 PM



Advertisments