function declaration overloading in C

T

Tobias Blomkvist

Hi,

I have some example C code and would like to know what a "good" behaving
C compiler would do. This is because I'm writing my own C- compiler that
will end up as open-source sometime in the future.

I'd recommend you to buy the actual standard. It isn't that expensive,
and a lot more reliable than peeking on perhaps flawed implementations
and mimic their behavior.
 
S

spartan3wiz

Hi,

I have some example C code and would like to know what a "good"
behaving C compiler would do. This is because I'm writing my own C-
compiler that will end up as open-source sometime in the future.

Normally I use Microsoft Visual C++ 2005 C-compiler for testing
because I'm a windows-based programmer. The below behavior describes
how Microsoft's C compiler behaves when using the "/TC" command line
parameter to restrict the C/C++ compiler to only accept C-like syntax
and using "/W4" to get the highest warning level.

Example Code 1:
-snip-
void main(void)
{
test( );
}

int test(int a)
{
return 0;
}
-snip-

This code compiles with 2 warnings:
warning C4013: 'test' undefined; assuming extern returning int
warning C4100: 'a' : unreferenced formal parameter

So it uses the call for test( ) as a declaration (with implicit return
type 'int'), is this standard?
Even though the body uses an inparameter of 'int' it still compiles
and executes correctly, is this standard? You can actually send any
number of parameters and any type and it still compiles and runs... it
does seem to behave more like standard C if I omit the "/TC" why is
that?

--------------------------------------------------------
Example Code 2:
-snip-
int test(int a)
{
return 0;
}

void main(void)
{
test();
}
-snip-

This code compiles with 1 error and 1 warning:
warning C4100: 'a' : unreferenced formal parameter
error C2198: 'test' : too few arguments for call

This seems more correct as the number of inparameters in the function
declaration does not match with the number of inparameters in the
function call ..

--------------------------------------------------------

Can somebody describe the above and it would be nice to hear how other
C compilers behave.

Best Regards
Magnus Wedmark
 
W

Walter Roberson

I have some example C code and would like to know what a "good"
behaving C compiler would do.
Example Code 1:
-snip-
void main(void)
{
test( );
}

int test(int a)
{
return 0;
}
-snip-
This code compiles with 2 warnings:
warning C4013: 'test' undefined; assuming extern returning int
warning C4100: 'a' : unreferenced formal parameter
So it uses the call for test( ) as a declaration (with implicit return
type 'int'), is this standard?

Yes in C89 and C95. Possibly not in C99 (I'd need to check references
on that.)
Even though the body uses an inparameter of 'int' it still compiles
and executes correctly, is this standard? You can actually send any
number of parameters and any type and it still compiles and runs...

The implicit declaration caused by mention of the function is
int test() where the () indicates that the number of parameters
it takes is unspecified. If you call such a function with a number
of parameters that differs from its actual number of parameters
in its definition, then the behaviour is undefined. For example it
would be valid for the calling routine to just push the return
address on a stack (because as far as it knows there are no parameters),
but for the called routine to think there are two items on the
stack (return address and parameter), thus leading the function to
attempt to return to whatever value just -happened- to be on the
stack in the slot the called routine thinks is the return address.
 
F

Flash Gordon

spartan3wiz wrote, On 25/03/08 19:51:
Hi,

I have some example C code and would like to know what a "good"
behaving C compiler would do. This is because I'm writing my own C-
compiler that will end up as open-source sometime in the future.

I think it would be nice if you went against the norm and produced a
compiler that by default conformed to the C standard with a high level
of additional warnings and the user had to explicitly switch on
extensions and turn the warning level down if required.

Also, as you are starting now it would probably a good thing if you
aimed for C99 conformance (i.e. the standard released in 1999) rather
than the old C89/C90/C95 standard.
Normally I use Microsoft Visual C++ 2005 C-compiler for testing
because I'm a windows-based programmer. The below behavior describes

Visual studio only conforms to C95 and by default has a number of
extensions enabled. You might consider also using gcc to compare against.

Also, you should really get a copy of the C standard, drafts are
available for free, including one which (modulo errors) is the latest
standard + all current updates. See http://clc-wiki.net/wiki/c_standard
how Microsoft's C compiler behaves when using the "/TC" command line
parameter to restrict the C/C++ compiler to only accept C-like syntax
and using "/W4" to get the highest warning level.

Example Code 1:
-snip-
void main(void)

void main is not one of the standard forms of main. You are allowed to
accept it as an extension if you choose, but I think following gcc's
lead and at elast producing a warning would be better.
{
test( );

C99 has removed implicit int, so calling test before declaring it now
requires a diagnostic. Even if you want to implement the older standard
then at least a warning would be useful.

Had you included a non-prototype declaration before the call, e.g.
int test();
then even under C99 no diagnostic (error or warning) would have been
required. However warning that there was no prototype in scope (a
prototype also includes parameter types) would be useful. It would also
be useful if you remembered how it had been called and produced an error
when you reached the definition if it did not match (remember to allow
for default argument promotions etc).

Also note that calling a function with an incorrect number of parameters
invokes "undefined behaviour". What this means to you as an implementer
is that you don't have to bother making it work.
}

int test(int a)
{
return 0;
}
-snip-

This code compiles with 2 warnings:
warning C4013: 'test' undefined; assuming extern returning int

This is useful but not required according to C95 which is what the
compiler conforms to (modulo bugs) but it is useful. You should note
that you are allowed to produce diagnostics (e.g. warnings) for anything
you like as far as the C standard is concerned.
warning C4100: 'a' : unreferenced formal parameter

This is useful but not required by any version of the C standard.
However it is useful to be able to disable the warning because some
times there are good reasons for not using a parameter.
So it uses the call for test( ) as a declaration (with implicit return
type 'int'), is this standard?

It was in C89/C95/C95 but is no longer valid in C99.
Even though the body uses an inparameter of 'int' it still compiles
and executes correctly, is this standard?

It is *allowed* to do what the programmer expected, but it is not
*required* to do what the programmer expected.
You can actually send any
number of parameters and any type and it still compiles and runs... it
does seem to behave more like standard C if I omit the "/TC" why is
that?

You are incorrect in believing it behaves more like standard C without
/TC. It would still be behaving entirely within what the standard
allowed if it failed to compile the above program, or if the compiled
program printed, "your mother is a bloated warthog" or reformatted your
hard disk.
--------------------------------------------------------
Example Code 2:
-snip-
int test(int a)
{
return 0;
}

void main(void)
{
test();
}
-snip-

This code compiles with 1 error and 1 warning:
warning C4100: 'a' : unreferenced formal parameter

This warning is not required but is useful.
error C2198: 'test' : too few arguments for call

A diagnostic is required in this instance (it does not have to be
meaningful and it does not have to be an error). The reason a diagnostic
is required in this instance is that a prototype (which also happens to
be a definition) is in scope.
This seems more correct as the number of inparameters in the function
declaration does not match with the number of inparameters in the
function call ..

See comments above.

Your first port of call should be the standard, although that can be
hard to read.
 
S

spartan3wiz

Thank you all for sharing your ideas/thoughts. The standard feel a bit
too hefty for me to buy and be of use, but I downloaded the 552 pages
PDF in case I can find some clues in there..

Thank you Walter for giving such exact notifications about the subject
in question.

My initial choice in this matter is to use yet another switch (/WX)
which transforms warnings to errors. By doing this the syntax for
getting a successful compilation looks more like what I'm looking
for. :)

But really I'm open for discussions so please post more comments in
the subject.

Magnus Wedmark
 
B

Bartc

Flash said:
spartan3wiz wrote, On 25/03/08 19:51:

I think it would be nice if you went against the norm and produced a
compiler that by default conformed to the C standard with a high level
of additional warnings and the user had to explicitly switch on
extensions and turn the warning level down if required.

Also, as you are starting now it would probably a good thing if you
aimed for C99 conformance (i.e. the standard released in 1999) rather
than the old C89/C90/C95 standard.

How much work is actually involved in creating a C compiler? Ie. for an
individual.

I know there's the compiler itself (convert a module of C to some format or
other). Maybe the preprocessor too.

But is an implementer also expected to create the entire runtime library?

And the tools to convert the compiler output to a runable program (linkers
and whatever else)?

I guess debuggers are not essential nor IDEs.

Just asking out of curiosity.
 
S

spartan3wiz

How much work is actually involved in creating a C compiler? Ie. for an
individual.

I know there's the compiler itself (convert a module of C to some format or
other). Maybe the preprocessor too.

But is an implementer also expected to create the entire runtime library?

And the tools to convert the compiler output to a runable program (linkers
and whatever else)?

I guess debuggers are not essential nor IDEs.

Just asking out of curiosity.

It's a lot of work.. I've not followed any made-out path and are just
doing this for fun so don't take this as rules.. far from it!

My initial aim was a complete compiler including everything and even
though I've scaled down it a bit, I'm still doing stuff the hard way
as a lesson. It is aimed for a 32-bit CPU included into a complete SOC
that a friend of mine is mostly responsible for. It does not follow
any known ISA, thus it has a unique instruction set.

I first looked at porting LCC/GCC/other but I liked the idea of doing
my own instead. I started out choosing COCO/R as the Scanner/Parser
generator tool and C# as language for personal reasons. I've written/
converted my own C grammar into COCO's ATG-syntax and are still
working with that as I go along. The output is a assembler text-file.
This file is then the input to the next step (the assembler) which
also is written from scratch (in JAVA), includes advanced features
like expressions and doubles as a emulator/debugger for most of the
SOC.

A nice thing is that the whole odd tool-suite is actually working both
in XP,Vista and Ubuntu 7.1 without recompilation.. :)

Today many C features are missing and I've been at this from time to
time for the last 2 years or so.. but I'm not giving up yet!

Magnus
 
G

Gordon Burditt

Also, as you are starting now it would probably a good thing if you
How much work is actually involved in creating a C compiler? Ie. for an
individual.

There's a lot of detail work interpreting the standard. It often
doesn't come out and say YOU MUST DO IT THIS WAY (e.g. two's
complement math), but often there are implications all over that
if you make THIS choice, you have to handle this other problem,
which generates inefficient code.

Or you make choices A1, B3, C2, D1, and E7, and then you discover
that no choice for F works. Sorry, you may have to back up and
revisit your previous choices.

I know there's the compiler itself (convert a module of C to some format or
other). Maybe the preprocessor too.

But is an implementer also expected to create the entire runtime library?

Yes, if there isn't one already. And you might need one for each
memory model you intend using. If the OS is already distributed
with headers and libraries (as a non-optional part), fine, use it
(but you'll need to be compatible with it). If the only other set
of headers and libraries for the platform is supplied by your
competitor, do you really want to tell your customer to buy his in
order to use yours?

You also have to be sure that the included headers and libraries
have licenses that your customers can tolerate. If you discover
that every executable (say, static-linked) they compile with intent
to distribute has to have a distribution license which costs $100
per copy of the executable, will anyone want to use your compiler
to distribute open-source binaries? I doubt it.
And the tools to convert the compiler output to a runable program (linkers
and whatever else)?

If the OS contains a linker as a non-optional part, consider using
it. It might not be adequate for your purposes, or maybe it will
be. Otherwise, supply your own or refer customers to where they
can buy one to make your compiler usable. (Linkers are more likely
to handle multiple languages, so even if yours is the only C
implementation on that platform, you may find a usable one.)
 
C

CBFalconer

Tobias said:
I'd recommend you to buy the actual standard. It isn't that
expensive, and a lot more reliable than peeking on perhaps flawed
implementations and mimic their behavior.

The free stuff will do just as well.

Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://c-faq.com/> (C-faq)
<http://benpfaff.org/writings/clc/off-topic.html>
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf> (C99)
<http://cbfalconer.home.att.net/download/n869_txt.bz2> (C99, txt)
<http://www.dinkumware.com/c99.aspx> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
<http://clc-wiki.net/wiki/C_community:comp.lang.c:Introduction>
 

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,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top