name decoration - why does this example code compile?

M

mastermagrath

Hi,

I'm about half way through Bruce Eckels thinking in C++ Vol 1. He gives
a very short example of how compiler function name decoration helps
remove subtle bugs by type-safe linkage. However, upon looking at the
example i understand why it fails to link but don't understand why it
even compiles. Here's the code, which split between 2 files Def.cpp and
Use.cpp:

//File Def.cpp
//Function definition
void f(int) {}

In the second file, the function is misdeclared and then called:


//File Use.cpp
//Function misdeclaration
void f(char);

int main() {
f(1); // Causes a linker error
}

I thought that C++ forces the user to declare all functions before use
so it can perform compile time error checking e.g. against proper type
usage. In the above example i would have expected the compiler to throw
up an error because in creating the object file for Use.cpp it would
see that i declare a function that takes a char but actually call it
with an integer. However, it does compile, and only barfs during the
link stage as it can't find the function definition of the version that
takes a char argument.
Can anyone tell me why it compiles?
Also, as a side question i also thought C++ forces the user to define
function arguments with a variable name, but again in Def.cpp the
function is defined only with a variable type.

Thanks in advance
 
J

Jonathan Mcdougall

mastermagrath said:
Hi,

I'm about half way through Bruce Eckels thinking in C++ Vol 1. He gives
a very short example of how compiler function name decoration helps
remove subtle bugs by type-safe linkage. However, upon looking at the
example i understand why it fails to link but don't understand why it
even compiles. Here's the code, which split between 2 files Def.cpp and
Use.cpp:

//File Def.cpp
//Function definition
void f(int) {}

In the second file, the function is misdeclared and then called:

//File Use.cpp
//Function misdeclaration
void f(char);

int main() {
f(1); // Causes a linker error
}

I thought that C++ forces the user to declare all functions before use
so it can perform compile time error checking e.g. against proper type
usage.

Yes it does.
In the above example i would have expected the compiler to throw
up an error because in creating the object file for Use.cpp it would
see that i declare a function that takes a char but actually call it
with an integer.

An int can be implictly converted to a char. This would have failed:

class A {};

void f(A a);

int main()
{
f(3); // cannot convert int 3 to an A
}
However, it does compile, and only barfs during the
link stage as it can't find the function definition of the version that
takes a char argument.
Can anyone tell me why it compiles?

It compiles because the code is legal. It doesn't link because void
f(char) is never defined.

Understand that the compiler has no "memory" between translation units.
As a programmer, you may know that f(int) and f(char) are intended to
be the same function, but for the compiler, everything is perfectly
kosher. However, the linker, which is in charge of "mapping" function
declaration to function definition, cannot find the required definition
and thus reports an error.
Also, as a side question i also thought C++ forces the user to define
function arguments with a variable name, but again in Def.cpp the
function is defined only with a variable type.

You thought wrong.


Jonathan
 
L

lesco

The number 1 is also a char. A char is just a number between 0 and 255.
Characters like 'A' are just aliases for the ascii number ( i.e. 'A' =
0x41).
That's why the type-checking doesn't fail and only the linker complains.
 
J

Jonathan Mcdougall

(e-mail address removed) wrote:

Please learn to quote correctly
(http://en.wikipedia.org/wiki/Top-post#Snipping.2Ftrimming and
http://cfaj.freeshell.org/google/).
The number 1 is also a char.

No. The litteral 1 is an int, but an int can be implictly converted to
a char.
A char is just a number between 0 and 255.

No. A char is a data type which is at least 1 byte and a byte is at
least 8 bits. Also, whether it is signed or not is implementation
defined. To be safe, you can only assume a char has a range of [0,
127].
Characters like 'A' are just aliases for the ascii number ( i.e. 'A' =
0x41).

Again, no. Characters have the value of the underlying character set:
ASCII on ASCII machines, EBCDIC on EBCDIC machines, etc.
That's why the type-checking doesn't fail and only the linker complains.

The reason it doesn't fail is simply that chars are implictly
convertible to int.

Check your facts before posting.


Jonathan
 
D

dj

Jonathan said:
Yes it does.


An int can be implictly converted to a char. This would have failed:

class A {};

void f(A a);

int main()
{
f(3); // cannot convert int 3 to an A
}


It compiles because the code is legal. It doesn't link because void
f(char) is never defined.

Understand that the compiler has no "memory" between translation units.
As a programmer, you may know that f(int) and f(char) are intended to
be the same function, but for the compiler, everything is perfectly
kosher. However, the linker, which is in charge of "mapping" function
declaration to function definition, cannot find the required definition
and thus reports an error.


You thought wrong.


Jonathan

What is the difference if the function f(char) in file use.cpp is
declared extern?
 
J

Jonathan Mcdougall

dj said:
What is the difference if the function f(char) in file use.cpp is
declared extern?

None whatsoever. A function always has external linkage (unless it is
static), so adding "extern" is redundant.


Jonathan
 
J

Jack Klein

(e-mail address removed) wrote:

Please learn to quote correctly
(http://en.wikipedia.org/wiki/Top-post#Snipping.2Ftrimming and
http://cfaj.freeshell.org/google/).


No. The litteral 1 is an int, but an int can be implictly converted to
a char.


No. A char is a data type which is at least 1 byte and a byte is at

No. A char is a data type which is exactly 1 byte, by definition. Even
on platforms where CHAR_BIT is 16 or 32 (fairly common today on DSPs).
least 8 bits. Also, whether it is signed or not is implementation
defined. To be safe, you can only assume a char has a range of [0,
127].

The rest is OK.
 
J

Jonathan Mcdougall

Jack said:
No. A char is a data type which is exactly 1 byte, by definition. Even
on platforms where CHAR_BIT is 16 or 32 (fairly common today on DSPs).

I was already thinking about the "at least 8 bits" part. My mistake.


Jonathan
 

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

Staff online

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top