function call with arguments which takes no arguments

Why the following code is compilable? The function abc() doesn't take any arguments, still i can call the function with arbitraty number of arguments. Even compiler doesn't show any warning. What the standard says?

----- file1.c ------ extern unsigned abc(); int main() { unsigned *chip_offset; abc(&chip_offset, 10); /* do something with pointer - which is errornous */ return 0; }

----- file2.c ----- unsigned abc() { unsigned some_address; some_address = 0xFFBA; return some_address; }

-Neo "If you don't program yourself, life will program you!"

Reply to
Neo
Loading thread data ...

But unless you're compiling this as C++, your source code doesn't say so. 'extern unsigned abc()' is an old-style, non-prototype declaration of abc(), which does *not* give the compiler any information about the number or types of arguments to abc(). It only specifies the return type (and that in an old-fashioned, deprecated way, lacking the 'int' after unsigned). The correct prototype declaration would be

extern unsigned int abc(void);

To avoid running into this problem in the future, you may want to enable whatever option your compiler has to make it insist on having prototype declarations in scope for all functions (in GCC it's

-Wstrict-prototypes).

And a nitpick: using 'extern' directly in a .c file is pretty much guaranteed to be a bad idea. It should only ever occur in header files. And the header file containing the above prototype should be #include'd in *both* file1.c and file2.c, to make sure it matches the definition and the usage of this function.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker
[...]

Such programs usually go by the family name of 'lint'. PClint appears to the be the generally accepted leader of the field in proprietary software; the FOSS world offers splint.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

Because you specifically said you weren't defining the arguments here. You should have used "unsigned abc(void);" for no arguments.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
Reply to
CBFalconer

Good Rules, Jack.

But technically, header files are source code files too. I was confused when I started to read your rules.

in fact, one could be perverse and write headers with the .c extension, although some toolsets may balk (or lose functionality) with this.

IMHO, the rules should be prefaced with:

In the following list of rules, "source code file" is distinct from "header file".

Rufus, Another Picker Of Nits

(although I have yet to learn to use the (void) argument list)

Reply to
Rufus V. Smith

In addition to Jack's good advice (most of which I've deleted), get yourself a copy of lint. A good lint will catch such things as missing prototypes, public functions that can/should be private etc... This is particularly useful when you've just started to change styles and the new style has not become second nature yet.

Robert

Reply to
R Adsett

And that's why some folks won't use C in high reliability systems.

Object modules _have_ to contain strong type information.

--
Nicholas O. Lindan, Cleveland, Ohio
Consulting Engineer:  Electronics; Informatics; Photonics.
Remove spaces etc. to reply: n o lindan at net com dot com
psst.. want to buy an f-stop timer? nolindan.com/da/fstop/
Reply to
Nicholas O. Lindan

Those rules don't affect the type information in the slightest. They do affect the external exposure of routines and objects, and the linkability of systems.

Banning C from so-called hi-reliability systems is because C intrinsically is unable to type things closely, and the presence of pointer arithmetic puts accuracy out of automatic control. Associated with that is the absence of range-checks, exacerbated by the fact that the language has no way to specify an arbitrary range.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
Reply to
CBFalconer

Very Good Explanation of function Prototypes..... this is often overlooked by most C programmers or 'coz of lazziness.

One point em nt clear about is What is the use of extern keyword in a function prototype. Should we use or not use extern keyword in a function prototype and WHY? Lets say for eg. :

------ main.c ----- #include "file1.h" #include "abc.h"

int main(void) { int i; i = sum(2,3); abc(); return 0; }

-------- file1.h ------- #ifndef __FILE1_H__ #define __FILE1_H__ int sum(int a, int b); #endif

-------- file1.c------- #include "file1.h" int sum(int a, int b) { return (a+b); }

------abc.h------ #ifndef __ABC_H__ #define __ABC_H__ void abc(void); #endif

-------abc.c------ #include "abc.h" #include "file1.h" void abc(void) { int i; i = sum(22,33); }

I compile the above Program as follows : gcc main.c file1.c abc.c -ansi -Wall -pedantic -Wstrict-prototypes

Clean compilation no warnings. O'kay! Now, should I declare int sum(int a, int b); as extern int sum(int a, int b); in file1.h if so, why???? (I've seen some ppl. do that way).

and there is also practice to code it something like this #ifdef __FILE1_C__ #define FILE1_EXTERN #else #define FILE1_EXTERN extern #endif

FILE1_EXTERN int sum(int a, int b);

A8.1 ...."objects and functions declared outside a function are taken to be static, with external linkage." K&R II Page 211. What is the meaning of the above line???

Thanks,

-Neo

Reply to
Neo
[... huge snip ... --- please, if you're not going to actually refer to any particular parts of such a long article, don't quote it in full...]

It doesn't matter. Assuming you followed the rules layed out earlier in this thread, there's no situation left where having 'extern' would make a difference.

For variables, you have to distinguish four cases of setting up a variable outside of any function (i.e. "at file scope").

extern int a; /* declaration */ int b; /* tentative definition */ int c = 0; /* definition, external linkage */ static int d; /* definition, internal linkage */

The tricky one is 'b': it can be equivalent to a declaration (like 'a'), or a definition auto-initialized to zero (like 'c'), depending on context. For functions, the case where it turns into a definition can't happen, so a and b are always equivalent, and the 'extern' is not necessary.

Common practice tends to save keystrokes and file size, by omitting the 'extern' in prototypes.

Please don't use this kind of names in this fashion. Names beginning with a double underscore aren't yours to use. They're reserved to the C implementation itself. If you use them yourself, you run a chance of conflicting with the implementation, causing all kinds of unwanted grief.

This is a hack. Whether it's an evil or a clever one lies in the eye of the beholder.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

... snip Jack Kleins explanation of prototypes ...

The answer is none. A prototype is either in a .c file, when it should be marked static and not be mentioned in the corresponding .h file, or is in a .h file, when it should not be marked static and specifies an access to the .c file.

... snip code example ...

For functions the static refers to their lifetime, not visibility. However the use of 'static' in their declaration/definition also removes the external linkage. The word static is used in two separate senses, only one of which is in the language. The actual qualifier 'static' in the code generally removes the default 'external linkage' and may add the 'static lifetime' within functions.

Well, at least I understand what I wrote. :-)

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
Reply to
CBFalconer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.