Tech Support > Computer Hardware > Microprocessors > function call with arguments which takes no arguments
function call with arguments which takes no arguments
Posted by Neo on January 19th, 2005


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!"



Posted by Hans-Bernhard Broeker on January 19th, 2005


Neo <timeless_illusion@yahoo.com> wrote:
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.

Posted by Neo on January 19th, 2005



"Hans-Bernhard Broeker" <broeker@physik.rwth-aachen.de> wrote in message
news:356tmbF2pu1cdU1@news.dfncis.de...
My compiler doesn't have such option. Is there any tool that i can use to
validate my programs for ISO-C90/ANSI std. compliance.

-Neo



Posted by Paul Burke on January 19th, 2005


Neo wrote:

What's the target, host OS, target OS (if any)?

Paul Burke

Posted by Neo on January 19th, 2005



"Paul Burke" <paul@scazon.com> wrote in message
news:356vauF4kc7epU1@individual.net...
target : TMS320C5402 DSP
host OS : Win XP
target OS : DSP/BIOS (by TI)

-Neo



Posted by Hans-Bernhard Broeker on January 19th, 2005


Neo <timeless_illusion@yahoo.com> wrote:
[...]
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.

Posted by CBFalconer on January 19th, 2005


Neo wrote:
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



Posted by Not Really Me on January 19th, 2005


Neo wrote:
If you are using TI's Code Composer Studio then there definitely is control
of the parser options. The setting is a pull-down on the Parser tab of the
Project -> Build Options dialog.

Scott



Posted by Neo on January 20th, 2005



"Not Really Me" <scott@exoXYZtech.com> wrote in message
news:357ch8F4jrqohU1@individual.net...
O'kay I turned on "Strict ANSI Mode (-ps)" Option.
But now compiler doesn't accept non-ansi extentions provided by the Compiler
itself. Like :
ioport unsigned port6000;
to declare an IO Port at 0x6000
How it is possible to compiler the code but still in ANSI mode.

-Neo



Posted by Jack Klein on January 20th, 2005


On Wed, 19 Jan 2005 15:59:33 +0530, "Neo"
<timeless_illusion@yahoo.com> wrote in comp.arch.embedded:

C allows function declarations with empty parentheses for backwards
compatibility with code from before the ANSI standard, when the
language did not have prototypes.

The C standard specifically states that when you call a function
without having a prototype in scope, if the call does not have the
correct number and type of parameters, the behavior is undefined.
That means it is strictly up to the programmer to make sure he gets it
correct if he/she chooses NOT to use prototypes. A compiler is NEVER
required to warn you about undefined behavior, and the C standard
washes its hands of any responsibility for the result.

There is no possible excuse at all for not using prototypes in all
function declarations and definitions in C. Prototypes are the single
most significant and important improvement in the 30+ year history of
the language. Anyone who claims to be a professional C programmer and
ever fails to use a prototype is deluding themselves.

Empty parentheses should never appear in a function declaration or
definition in C. NEVER.

In a later post in the thread, you talked about using TI's Code
Composer Studio. I use if for a different DSP family, so I don't know
if yours is the same, but you don't want the "strict ANSI" setting on
the Parser page. See if you have a check box for "Issue Nonserious
Warnings" on the Diagnostics page.

That probably won't catch this particular error, since it might equate
the non-prototype declaration as a prototype, but I don't know for
sure because such things never appear in my code.

If you are going to be a professional programmer, start learning some
basic rules now:

1. The 'extern' keyword should NEVER appear in a source code file.

2. There should NEVER be a function prototype in a source code file,
unless it has the function is static and defined in the same source
code file.

3. All functions not static, and all external data, MUST be
prototypes and/or declared in a header, and that header MUST be
included by the source file that defines the function/data as well as
every source file that calls/references the externals.

4. There are no function declarations or definitions with (). ALL
function declarations MUST be full prototypes. There is no "int
main()", there is ONLY "int main(void)". There is no "extern unsigned
abc()", there is ONLY "extern unsigned int abc(void)".

If you do this right, the compiler will catch every single mis-matched
function call.

Some programmers think they are too experienced or too talented to
have to follow what they consider "nit picky" rules like this. That
is just a case of their egos outweighing their judgment. If you don't
code like this, you are an accident waiting to happen, and it WILL
happen, no matter how good or experienced you are.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html

Posted by CBFalconer on January 20th, 2005


Neo wrote:
You isolate such things into a set of non-portable routines in a
separate file, and compile them without the ANSI setting. The bulk
of your system is written in portable code. It can still call
those non-portable routines. You might have, for example:

unsigned char getport6000(void);
void putport6000(unsigned char data);

in a separate file, with appropriate .h header files. Your main
program calls these.

--
"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



Posted by Rufus V. Smith on January 20th, 2005



"Jack Klein" <jackklein@spamcop.net> wrote in message
news:gmduu0pjtt625jpe6l0otdfopk75m6dnr0@4ax.com...
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)




Posted by R Adsett on January 20th, 2005


In article <gmduu0pjtt625jpe6l0otdfopk75m6dnr0@4ax.com>,
jackklein@spamcop.net says...

<snip>

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

Posted by Nicholas O. Lindan on January 20th, 2005


jackklein@spamcop.net says...

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/

Posted by CBFalconer on January 21st, 2005


"Nicholas O. Lindan" wrote:
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



Posted by Neo on January 21st, 2005



"Jack Klein" <jackklein@spamcop.net> wrote in message
news:gmduu0pjtt625jpe6l0otdfopk75m6dnr0@4ax.com...
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



Posted by Hans-Bernhard Broeker on January 21st, 2005


Neo <timeless_illusion@yahoo.com> wrote:

[... 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.

Posted by CBFalconer on January 21st, 2005


Neo wrote:
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




Similar Posts