473,408 Members | 1,623 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

The ODR thing again

If I have a non-inline function definition in a header file with header
guards like this:
#ifndef HEADER_GUARD_H
#define HEADER_GUARD_H

int foo(){ return 42; }
namespace { bar() { return 666; }
#endif

that definition of foo() will only appear once in any given translation
unit, correct? "Translation unit" is a synonym for "file scope", is it
not? Am I correct that the implementation is not required to detect ODR
violations across TUs? Is it, therefore, /possible/ that a conforming
compiler could compile code where foo() is defined in multiple TUs?

My understanding of the Standard is that names within an unnamed namespace
have file scope. Does that mean I should be able to define bar() in an
unnamed namespace and never get an ODR violation from the file with the
definition (within header guards) being #included in in multiple TUs within
the same program?
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 2 '06 #1
11 2165
* Steven T. Hatton:
If I have a non-inline function definition in a header file with header
guards like this:
#ifndef HEADER_GUARD_H
#define HEADER_GUARD_H

int foo(){ return 42; }
namespace { bar() { return 666; }
#endif

that definition of foo() will only appear once in any given translation
unit, correct?
If the header file is used as intended.

"Translation unit" is a synonym for "file scope", is it not?
No.

In practical terms, a translation unit is comprised of the program text
that results from preprocessing of one C++ source file.

File scope refers to declarations outside any class or function.

Am I correct that the implementation is not required to detect ODR
violations across TUs?
Yes.

Is it, therefore, /possible/ that a conforming
compiler could compile code where foo() is defined in multiple TUs?
Yes (to make the code correct, declare the function as 'inline', that's
what that keyword is for).

My understanding of the Standard is that names within an unnamed namespace
have file scope.
They have namespace scope, which is what's usually meant by "file scope".

The "unnamed" namespace is not really unnamed but has an automatically
generated unique name for that translation unit.

Names defined in that namespace are then imported to the global
namespace as if

namespace{ void bar(){} }

is translated to

namespace veryUniqueName{ void bar(){} }

using namespace veryUniqueName;

which you may recognize from having done just about the same for
namespace std (at least, most students do).

Does that mean I should be able to define bar() in an
unnamed namespace and never get an ODR violation from the file with the
definition (within header guards) being #included in in multiple TUs within
the same program?
bar() will not violate the ODR, while foo will.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 2 '06 #2
Alf P. Steinbach wrote:
* Steven T. Hatton:
>
>"Translation unit" is a synonym for "file scope", is it not?

No.

In practical terms, a translation unit is comprised of the program text
that results from preprocessing of one C++ source file.
So, in terms of compiling a C++ program "file" means the source file, and
everything #included directly or indirectly in the source file. This is
also called a translation unit.
File scope refers to declarations outside any class or function.
Is there any scope in a translation unit which is not coincident with file
scope?
>Is it, therefore, /possible/ that a conforming
compiler could compile code where foo() is defined in multiple TUs?

Yes (to make the code correct, declare the function as 'inline', that's
what that keyword is for).
To be pedantic, is it not more correct to say that the storage class
specifier 'static' used at file scope is intended for that purpose? I
suspect both inline and static will have the same effect in most cases. The
one place in which I found the use of an unnamed namespace valuable was not
involving functions, so I probably should have avoided using a function in
the is example. Where I found it useful was in defining const char[]
variables to pass as template parameters.
>
>My understanding of the Standard is that names within an unnamed
namespace have file scope.

They have namespace scope, which is what's usually meant by "file scope".

The "unnamed" namespace is not really unnamed but has an automatically
generated unique name for that translation unit.

Names defined in that namespace are then imported to the global
namespace as if

namespace{ void bar(){} }

is translated to

namespace veryUniqueName{ void bar(){} }

using namespace veryUniqueName;

which you may recognize from having done just about the same for
namespace std (at least, most students do).
If by student you mean a person who reads a book on how to program in C++,
and teacher you mean an author of such a book, I will say that the use
of 'using namespace' directives is far more common in code written by
teachers than it is, or ever has been, in my code. When I started trying
to learn C++ in earnest I began with outdated texts that used <iostream.h>
and put std::cout in the global namespace. When I compiled the code, I got
warning messages telling me my code was using deprecated functionality.

That made me very frustrated and angry. I asked people for help, and they
told me how to contaminate the global namespace with a `using' directive.
It seemed rather pointless to have this convoluted feature which seemed to
serve no other purpose than to intimidate the novice. I therefore
investigated the proper meaning and intent of namespaces.
>
>Does that mean I should be able to define bar() in an
unnamed namespace and never get an ODR violation from the file with the
definition (within header guards) being #included in in multiple TUs
within the same program?

bar() will not violate the ODR, while foo will.
How do the use of `inline', `static', and unnamed namespaces differ in their
effect? That is, other than the fact that `inline' is not applicable to
variables.

Sutter and Alexandrescu advise against all of these. If I understand
correctly, this is because it leads to redundant instances of object code
being placed on the stack at runtime.

And then there's extern...
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 3 '06 #3
* Steven T. Hatton:
* Alf P. Steinbach:
>>
Names defined in [an anonymous namespace] are then imported to the global
namespace as if

namespace{ void bar(){} }

is translated to

namespace veryUniqueName{ void bar(){} }

using namespace veryUniqueName;

which you may recognize from having done just about the same for
namespace std (at least, most students do).

If by student you mean a person who reads a book on how to program in C++,
and teacher you mean an author of such a book, I will say that the use
of 'using namespace' directives is far more common in code written by
teachers than it is, or ever has been, in my code.
Sorry, I meant no disrespect.
[snip]
How do the use of `inline', `static', and unnamed namespaces differ in their
effect? That is, other than the fact that `inline' is not applicable to
variables.

Sutter and Alexandrescu advise against all of these. If I understand
correctly, this is because it leads to redundant instances of object code
being placed on the stack at runtime.

And then there's extern...
This has to do with linkage and the One Definition Rule (ODR).

Linkage: which names are matched (bound) to which declarations, across
translation units. A pure declaration of a name N must be matched to a
definition of N if N is used at run-time. An example where N is only
used at compile time and so needs no definition: sizeof(N).

There is external linkage, internal linkage and no linkage.

When a name N has external linkage a pure declaration of N can be
matched to a definition in another translation unit. The ODR: unless N
is (a) declared 'inline' or (b) is a template specialization, there must
not be more than one definition. In the exceptional cases (a) and (b),
which are really the same case but has no general C++ desciptive term,
if there is more than one definition they must all be the same (but no
diagnostic required for violation), which means in practice that the
linker can just pick the first definition it encounters and discard the
rest, which is the reason that at the tool level cases (a) and (b)
multiple definitions are known as "discardable" records.

When a name N has internal linkage a pure declaration of N can only be
matched to a definition in the same translation unit. This means the
name N can be used, differently or in the same way, in any number of
translation units. There are two ways to get internal linkage: 'static'
and 'const'; 'static' used for this purpose (it has far too many
meanings!) is deprecated for data but not for functions.

When a name N has no linkage a pure declaration of N isn't matched to
any definition. That means that if N is used at run time it can't be
just declared and defined elsewhere, it must be defined in the
declaration. A local class has no linkage.

The main point of an anonymous namespace is to keep external linkage (so
that e.g. the template mechanism can be employed, because actual
template parameters must have external linkage) but provide unique
per-translation unit names so as to avoid name conflicts across
translation units.

I doubt that Herb and Andrei advice against 'inline', 'static' and
anonymous namespaces in general.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 3 '06 #4
Alf P. Steinbach wrote:
* Steven T. Hatton:
>And then there's extern...

This has to do with linkage and the One Definition Rule (ODR).

Linkage: which names are matched (bound) to which declarations, across
translation units. A pure declaration of a name N must be matched to a
definition of N if N is used at run-time. An example where N is only
used at compile time and so needs no definition: sizeof(N).

There is external linkage, internal linkage and no linkage.

When a name N has external linkage a pure declaration of N can be
matched to a definition in another translation unit. The ODR: unless N
is (a) declared 'inline' or (b) is a template specialization, there must
not be more than one definition. In the exceptional cases (a) and (b),
which are really the same case but has no general C++ desciptive term,
if there is more than one definition they must all be the same (but no
diagnostic required for violation), which means in practice that the
linker can just pick the first definition it encounters and discard the
rest, which is the reason that at the tool level cases (a) and (b)
multiple definitions are known as "discardable" records.

When a name N has internal linkage a pure declaration of N can only be
matched to a definition in the same translation unit. This means the
name N can be used, differently or in the same way, in any number of
translation units. There are two ways to get internal linkage: 'static'
and 'const'; 'static' used for this purpose (it has far too many
meanings!) is deprecated for data but not for functions.

When a name N has no linkage a pure declaration of N isn't matched to
any definition. That means that if N is used at run time it can't be
just declared and defined elsewhere, it must be defined in the
declaration. A local class has no linkage.

The main point of an anonymous namespace is to keep external linkage (so
that e.g. the template mechanism can be employed, because actual
template parameters must have external linkage) but provide unique
per-translation unit names so as to avoid name conflicts across
translation units.

I doubt that Herb and Andrei advice against 'inline', 'static' and
anonymous namespaces in general.
Wanna bet?

Ironically, when I looked more closely at the section "Do not define
entities with linkage in a header file", I saw the the way of getting
around that is to use `extern'. I haven't tried it yet, but I believe I
now understand why `extern' never worked for me. I was trying to define
the entity in /one/ of the header files, rather than in an implementation
file.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 4 '06 #5
* Steven T. Hatton:
Alf P. Steinbach wrote:
>I doubt that Herb and Andrei advice against 'inline', 'static' and
anonymous namespaces in general.

Wanna bet?
No, I see you: quote that advice if you think it exists.

Ironically, when I looked more closely at the section "Do not define
entities with linkage in a header file", I saw the the way of getting
around that is to use `extern'.
Then you have misunderstood.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 4 '06 #6
Alf P. Steinbach wrote:
* Steven T. Hatton:
>Alf P. Steinbach wrote:
>>I doubt that Herb and Andrei advice against 'inline', 'static' and
anonymous namespaces in general.

Wanna bet?

No, I see you: quote that advice if you think it exists.
In the section titled "Do not define entities with linkage in a header
file", they don't explicitly advise against header files with inline
functions. OTOH, they do not propose the use of `inline' as a means of
defining functions arbitrarily in a header file. Functions that already
have a reason to be inline /do/ belong in a header file.
>Ironically, when I looked more closely at the section "Do not define
entities with linkage in a header file", I saw the the way of getting
around that is to use `extern'.

Then you have misunderstood.
<quote>
The solution is simple - put just the declaration in a header:

extern int fudgeFactor;
extern string hello;
void foo(); //extern for functions is optional

The actual definitions go in a single implementation file:

int fudgeFactor;
string hello("Hello, world!");
void foo(){/*...*/}
</quote>
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 4 '06 #7
* Steven T. Hatton:
Alf P. Steinbach wrote:
>* Steven T. Hatton:
>>Alf P. Steinbach wrote:
I doubt that Herb and Andrei advice against 'inline', 'static' and
anonymous namespaces in general.
Wanna bet?
No, I see you: quote that advice if you think it exists.

In the section titled "Do not define entities with linkage in a header
file", they don't explicitly advise against header files with inline
functions. OTOH, they do not propose the use of `inline' as a means of
defining functions arbitrarily in a header file. Functions that already
have a reason to be inline /do/ belong in a header file.
>>Ironically, when I looked more closely at the section "Do not define
entities with linkage in a header file", I saw the the way of getting
around that is to use `extern'.
Then you have misunderstood.
<quote>
The solution is simple - put just the declaration in a header:

extern int fudgeFactor;
extern string hello;
void foo(); //extern for functions is optional

The actual definitions go in a single implementation file:

int fudgeFactor;
string hello("Hello, world!");
void foo(){/*...*/}
</quote>
I don't understand what you think, what the misconceptions are.

The above is meaningless to me.

I and others will be happy to answer simple questions.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 4 '06 #8
Alf P. Steinbach wrote:
* Steven T. Hatton:
>Alf P. Steinbach wrote:
>>>Ironically, when I looked more closely at the section "Do not define
entities with linkage in a header file", I saw the the way of getting
around that is to use `extern'.
Then you have misunderstood.
<quote>
The solution is simple - put just the declaration in a header:

extern int fudgeFactor;
extern string hello;
void foo(); //extern for functions is optional

The actual definitions go in a single implementation file:

int fudgeFactor;
string hello("Hello, world!");
void foo(){/*...*/}
</quote>

I don't understand what you think, what the misconceptions are.

The above is meaningless to me.
It is directly quoted from _C++ Coding Standards_ page 112.
I and others will be happy to answer simple questions.
What have I misunderstood?
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 4 '06 #9
* Steven T. Hatton:
Alf P. Steinbach wrote:
>* Steven T. Hatton:
>>Alf P. Steinbach wrote:
>>>>Ironically, when I looked more closely at the section "Do not define
entities with linkage in a header file", I saw the the way of getting
around that is to use `extern'.
Then you have misunderstood.
<quote>
The solution is simple - put just the declaration in a header:

extern int fudgeFactor;
extern string hello;
void foo(); //extern for functions is optional

The actual definitions go in a single implementation file:

int fudgeFactor;
string hello("Hello, world!");
void foo(){/*...*/}
</quote>
I don't understand what you think, what the misconceptions are.

The above is meaningless to me.

It is directly quoted from _C++ Coding Standards_ page 112.
The quote is (I take your word for that) but not the quote's context
here, as a solution to... something.

>I and others will be happy to answer simple questions.

What have I misunderstood?
That's the question, yes.

I don't understand what the misconceptions or lacking understanding
might be. I'm baffled, befuddled, perplexed etc. by the above. It's
possible that the authors are presenting a rule-of-thumb that mostly
helps newbies to avoid violating the ODR. But then there should have
been discussion of 'inline' and 'template', which are the proper devices
to use for avoiding ODR violations when one wants or needs to define
entities with linkage in header files (surely /Andrei/, the master of
templates, cannot be advicing to not put template definitions, which
have linkage, in header files). Are you sure the section's title is
quoted correctly and entirely, and that there's no such discussion?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 4 '06 #10
Alf P. Steinbach wrote:
* Steven T. Hatton:
>Alf P. Steinbach wrote:
>>* Steven T. Hatton:
Alf P. Steinbach wrote:
>>>>>Ironically, when I looked more closely at the section "Do not define
>entities with linkage in a header file", I saw the the way of getting
>around that is to use `extern'.
Then you have misunderstood.
<quote>
The solution is simple - put just the declaration in a header:

extern int fudgeFactor;
extern string hello;
void foo(); //extern for functions is optional

The actual definitions go in a single implementation file:

int fudgeFactor;
string hello("Hello, world!");
void foo(){/*...*/}
</quote>
I don't understand what you think, what the misconceptions are.

The above is meaningless to me.

It is directly quoted from _C++ Coding Standards_ page 112.

The quote is (I take your word for that) but not the quote's context
here, as a solution to... something.

>>I and others will be happy to answer simple questions.

What have I misunderstood?

That's the question, yes.

I don't understand what the misconceptions or lacking understanding
might be. I'm baffled, befuddled, perplexed etc. by the above. It's
possible that the authors are presenting a rule-of-thumb that mostly
helps newbies to avoid violating the ODR. But then there should have
been discussion of 'inline' and 'template', which are the proper devices
to use for avoiding ODR violations when one wants or needs to define
entities with linkage in header files (surely /Andrei/, the master of
templates, cannot be advicing to not put template definitions, which
have linkage, in header files).
Well, obviously, without the availability of `export' in C++ a
implementation, one cannot put template definitions in implementation files
following the conventions used for non-template constructs. Yes, they make
exceptions for those. They also make exceptions for inline functions. The
reason to declare a function inline is not, however, to avoid ODR
violations. It is to take advantage of the performance improvements
available when the compiler has the entire definition at its disposal, etc.
The ODR immunity is a consequence of the design, not the motive for it.
Are you sure the section's title is
quoted correctly and entirely,
Yes.

http://www.gotw.ca/publications/c++cs.htm
61. Don?t define entities with linkage in a header file. 112
and that there's no such discussion?
I never said there is no such discussion. I will say, however, that the
argument against entities with linkage in header files goes beyond avoiding
ODR violations.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 4 '06 #11
* Steven T. Hatton:
The
reason to declare a function inline is not, however, to avoid ODR
violations. It is to take advantage of the performance improvements
available when the compiler has the entire definition at its disposal, etc.
The ODR immunity is a consequence of the design, not the motive for it.
That, you have completely misunderstood. ;-)

>Are you sure the section's title is
quoted correctly and entirely,

Yes.

http://www.gotw.ca/publications/c++cs.htm
61. Don?t define entities with linkage in a header file. 112
>and that there's no such discussion?

I never said there is no such discussion. I will say, however, that the
argument against entities with linkage in header files goes beyond avoiding
ODR violations.
Does it?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 4 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: GG | last post by:
Hi all, Here's an idea for a framework I thought about because I can make use of it in my project. Maybe such a thing exists, if so, I'd like pointers; if not, I'll start working on it myself. ...
10
by: John Benson | last post by:
Hi, I see a lot of posts asking about "the best Python book." In my experience, there is no such thing, but there are a lot of good books that will help you along in different ways, and at...
9
by: syd | last post by:
I don't even know where to begin. This is just bizarre. I just picked up the Gnuplot.py module (a light interface to gnuplot commands) and was messing around with it today. I've got a tiny...
231
by: Brian Blais | last post by:
Hello, I saw on a couple of recent posts people saying that casting the return value of malloc is bad, like: d=(double *) malloc(50*sizeof(double)); why is this bad? I had always thought...
4
by: Luke Matuszewski | last post by:
Here are some questions that i am interested about and wanted to here an explanation/discussion: 1. (general) Is the objectness in JavaScript was supported from the very first version of it (in...
45
by: dolphin | last post by:
Is it a good thing that program mix C and C++?
104
by: JohnQ | last post by:
Well apparently not since one can step thru template code with a debugger. But if I was willing to make the concession on debugging, templates would be strictly a precompiler thing? I have a...
1
by: Gav | last post by:
Within my application I have a TabControl and I am adding TabPages in dynamically at run time. My problem is that I am able to create the same TabPage twice, ie. I click on button 1 it creates...
25
by: Dmitry S. Makovey | last post by:
Hi, after hearing a lot about decorators and never actually using one I have decided to give it a try. My particular usecase is that I have class that acts as a proxy to other classes (i.e....
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.