Are template variables allowed within multiple translation units and effectively merged? - c++

See the following:
https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule
http://eel.is/c++draft/basic.def.odr#12
It states that multiple definitions of class templates, static data members of class templates, partial template specializations, etc are allowed and will act as one single definition. Great... but it does not mention variable templates anywhere?
If I have the following in multiple translation units:
template<typename T>
T my_data{};
inline void test() {
my_data<int> = 1;
}
Will each translation unit will be given their own definition of my_data resulting in multiple symbols, or will they all be effectively merged into a single definition within the program where calling test() in one translation unit will modify the variable for another translation unit?
Where in the standard does it mention this behavior?

According to the c++14 standard [basic.def]/4:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required.
So if my_data<T> is ord-used with the same template argument in multiple translation unit, you should have a odr-violation (without any diagnostic). inline variables appeared in c++17 to solve that problem and this is why type_traits *_v family of variable template are declared inline.
In practice, with Gcc and Clang (at least, I cannot check other compilers), you will not get any odr violation because template variables have "vague linkage" (as if they were declared inline).
You can check it with nm. If you run this command line g++ -c test.cpp -std=c++14 && nm test.o | c++filt | grep my_data, you should see that my_data<int> is a symbol of categorie u which is according to nm documentation :
The symbol is a unique global symbol. This is a GNU extension to the standard set of ELF symbol bindings. For such a symbol the dynamic linker will make sure that in the entire process there is just one symbol with this name and type in use.
In Core issue #1849 one can read this obscure sentence:
The description in 6.2 [basic.def.odr] paragraph 6 of when entities can be multiply-declared in a program does not, but should, discuss variable templates.
I would bet that if all compilers give to variable templates a vague linkage, a future revision of the standard may reflect that. But for now we should use the inline specifier as it is done in the stl.

Related

Why is the symbol of member function weak?

I compiled this C++ code with g++ (7.3.0).
struct C {
__attribute__((noinline)) int foo() { return 0; };
};
int bar(C &c) { return c.foo(); }
And using nm I found that foo is weak. Is that due to the C++ specification or a decision of GCC?
The experiment flow:
$ g++ test.cpp -c -Og
$ nm test.o
0000000000000000 T _Z3barR1C
0000000000000000 W _ZN1C3fooEv
Is that C++ specification or decision of GCC?
A bit of both. Not that the C++ specification deals with strong or weak symbols (it doesn't). But it does affect GCC's behavior, since usually extensions try to build upon standard mandated behavior.
When you define a member function in the class body, it's automatically an inline function. In the C++ language, an inline function is a function that can have multiple definitions, so long as they appear in different translation units. It's not a problem, because in C++, an inline function must have the exact same definition in every translation unit (down to the token sequence). So even though they are "different" definitions, they are identical, and so can be reduced to a single one at some point.
The function doesn't have to actually be inlined at the call site. As far as C++ is concerend, inline is about the one-definition rule and linkage. So you have that, there can be multiple definitions of C::foo according to the spec.
And then you specify __attribute__((noinline)), so the function cannot be physically inlined, and so every TU must contain a symbol for the function.
This leaves only one choice. The symbol must be weak, otherwise the different symbols in different translation units will interfere with eachother. By making the symbol weak, you can have your mandatory definition and avoid physically inlining the function, while the C++ specification is upheld. Those different symbols stand for the exact same function, and so any one of them can "win" when linking.

Different compilation results not using extern in C vs in C++

When I declare a global variable in two different source files and only define it in one of the source files, I get different results compiling for C++ than for C. See the following example:
main.c
#include <stdio.h>
#include "func.h" // only contains declaration of void print();
int def_var = 10;
int main() {
printf("%d\n", def_var);
return 0;
}
func.c
#include <stdio.h>
#include "func.h"
/* extern */int def_var; // extern needed for C++ but not for C?
void print() {
printf("%d\n", def_var);
}
I compile with the following commands:
gcc/g++ -c main.c -o main.o
gcc/g++ -c func.c -o func.o
gcc/g++ main.o func.o -o main
g++/clang++ complain about multiple definition of def_var (this is the behaviour I expected, when not using extern).
gcc/clang compile just fine. (using gcc 7.3.1 and clang 5.0)
According to this link:
A tentative definition is a declaration that may or may not act as a definition. If an actual external definition is found earlier or later in the same translation unit, then the tentative definition just acts as a declaration.
So my variable def_var should be defined at the end of each translation unit and then result in multiple definitions (as it is done for C++). Why is that not the case when compiling with gcc/clang?
This isn't valid C either, strictly speaking. Says as much in
6.9 External definitions - p5
An external definition is an external declaration that is also a
definition of a function (other than an inline definition) or an
object. If an identifier declared with external linkage is used in an
expression (other than as part of the operand of a sizeof or _Alignof
operator whose result is an integer constant), somewhere in the entire
program there shall be exactly one external definition for the
identifier; otherwise, there shall be no more than one.
You have two definitions for an identifier with external linkage. You violate that requirement, the behavior is undefined. The program linking and working is not in opposition to that. It's not required to be diagnosed.
And it's worth noting that C++ is no different in that regard.
[basic.def.odr]/4
Every program shall contain exactly one definition of every non-inline
function or variable that is odr-used in that program outside of a
discarded statement; no diagnostic required. The definition can appear
explicitly in the program, it can be found in the standard or a
user-defined library, or (when appropriate) it is implicitly defined
(see [class.ctor], [class.dtor] and [class.copy]). An inline function
or variable shall be defined in every translation unit in which it is
odr-used outside of a discarded statement.
Again, a "shall" requirement, and it says explicitly that no diagnostic is required. As you may have noticed, there's quite a bit more machinery that this paragraph can apply to. So the front ends for GCC and Clang probably need to work harder, and as such are able to diagnose it, despite not being required to.
The program is ill-formed either way.
As M.M pointed out in a comment, the C standard has an informative section that mentions the very extension in zwol's answer.
J.5.11 Multiple external definitions
There may be more than one external definition for the identifier of
an object, with or without the explicit use of the keyword extern; if
the definitions disagree, or more than one is initialized, the
behavior is undefined (6.9.2).
I believe you are observing an extension to C known as "common symbols", implemented by most, but not all, Unix-lineage C compilers, originally (IIUC) for compatibility with FORTRAN. The extension generalizes the "tentative definitions" rule described in StoryTeller's answer to multiple translation units. All external object definitions with the same name and no initializer,
int foo; // at file scope
are collapsed into one, even if they appear in more than one TU, and if there exists an external definition with an initializer for that name,
int foo = 1; // different TU, also file scope
then all of the external definitions with no initializers are treated as external declarations. C++ compilers do not implement this extension, because (oversimplifying) nobody wanted to figure out what it should do in the presence of templates. For GCC and Clang, you can disable the extension with -fno-common, but other Unix C compilers may not have any way to turn it off.

Does C++ allow unused variables to have multiple definitions? [duplicate]

The standard seems to imply that there is no restriction on the number of definitions of a variable if it is not odr-used (§3.2/3):
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
It does say that any variable can't be defined multiple times within a translation unit (§3.2/1):
No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.
But I can't find a restriction for non-odr-used variables across the entire program. So why can't I compile something like the following:
// other.cpp
int x;
// main.cpp
int x;
int main() {}
Compiling and linking these files with g++ 4.6.3, I get a linker error for multiple definition of 'x'. To be honest, I expect this, but since x is not odr-used anywhere (as far as I can tell), I can't see how the standard restricts this. Or is it undefined behaviour?
Your program violates the linkage rules. C++11 §3.5[basic.link]/9 states:
Two names that are the same and that are declared in different scopes shall denote the same
variable, function, type, enumerator, template or namespace if
both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and
both names refer to members of the same namespace or to members, not by inheritance, of the same class; and
when both names denote functions, the parameter-type-lists of the functions are identical; and
when both names denote function templates, the signatures are the same.
(I've cited the complete paragraph, for reference. The second two bullets do not apply here.)
In your program, there are two names x, which are the same. They are declared in different scopes (in this case, they are declared in different translation units). Both names have external linkage and both names refer to members of the same namespace (the global namespace).
These two names do not denote the same variable. The declaration int x; defines a variable. Because there are two such definitions in the program, there are two variables in the program. The name "x" in one translation unit denotes one of these variables; the name "x" in the other translation unit denotes the other. Therefore, the program is ill-formed.
You're correct that the standard is at fault in this regard. I have a feeling that this case falls into the gap between 3.2p1 (at most one definition per translation unit, as in your question) and 3.2p6 (which describes how classes, enumerations, inline functions, and various templates can have duplicate definitions across translation units).
For comparison, in C, 6.9p5 requires that (my emphasis):
An external definition is an external declaration that is also a definition of a function
(other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof or _Alignof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.
If standard does not say anything about definitions of unused variables then you can not imply that there may be multiple:
Undefined behavior may also be expected when this International
Standard omits the description of any explicit definition of
behavior.
So it may compile and run nicely or may stop during translation with error message or may crash runtime etc.
EDIT: See James McNellis answer the standard indeed actually has rules about it.
There is no error in compiling that, the error is in its linkage. By default your global variable or functions are public to other files(have extern storage) so at the end when linker want to link your code it see two definition for x and it can't select one of them, so if you do not use x of main.cpp in other.cpp and vice-verse make them static(that means only visible to the file that contain it)
// other.cpp
static int x;
// main.cpp
static int x;

inline keyword for templates [duplicate]

This question already has answers here:
Does it make any sense to use inline keyword with templates?
(4 answers)
Closed 8 years ago.
This code will be placed in a header file:
template<typename TTT>
inline Permutation<TTT> operator * (const Cycle<TTT>& cy, const Permutation<TTT>& p)
{
return Permutation<TTT>(cy)*p;
}
Is inline necessary to avoid a linker error?
If this function is not a template and the header file is used in more than one .cpp file, inline is necessary to avoid a liker error complaining about multiple definitions for a function. It seems linker ignores this for templates.
Is inline necessary to avoid a linker error?
On a function template, no. Templates, like inline functions, are subject to a more relaxed One Definition Rule which allows multiple definitions - as long as the definitions are identical and in separate translation units.
As you say, inline would be necessary if you wanted to define a non-template function in a header; non-inline functions are subject to a more strict One Definition Rule, and can only have one definition in a program.
For the gory details, this is specified by C++11 3.2/5:
There can be more than one definition of a class type, inline function with
external linkage, class template, non-static function template, static data member
of a class template, member function of a class template, or template specialization for
which some template parameters are not specified in a program provided that each definition
appears in a different translation unit, and provided the definitions satisfy the following requirements.
(The "following requirements" basically say that the definitions must be identical).
Consider that a template function (or function template if you prefer) is not a function at all. It is rather a recipe to create a function. The actual function is only created when and where the template is instantiated. So you do not need the inline keyword here, because template functions will not result in multiple-definition linker errors because they are not actually defined (from the linker's perspective) until they are used.
Expanding on Mike Seymour's answer -- the paragraph (3.2/5) he cites in in the Standard refers to a concept called "vague linkage". Basically, it's a way of saying "we need this to exist somewhere in the resulting binary, but we don't have a clear-cut home for it in any specific object file we're emitting." On modern platforms (Windows, ELF systems such as Linux, and OS X), this is implemented using a mechanism known as COMDAT support that allows the compiler to simply generate the instantiations and other vague linkage items (vtables, typeinfos, and inline function bodies) as-needed -- the linker then is free to throw out the duplicates:
When used with GNU ld version 2.8 or later on an ELF system such as GNU/Linux or Solaris > 2, or on Microsoft Windows, duplicate copies of these constructs will be discarded at
link time. This is known as COMDAT support.
This is discussed in more detail in the GCC manual (quote snipped as the Cfront model is irrelevant for modern compilers):
C++ templates are the first language feature to require more intelligence from the
environment than one usually finds on a UNIX system. Somehow the compiler and linker
have to make sure that each template instance occurs exactly once in the executable if
it is needed, and not at all otherwise. There are two basic approaches to this problem,
which are referred to as the Borland model and the Cfront model.
Borland model
Borland C++ solved the template instantiation problem by adding the code equivalent
of common blocks to their linker; the compiler emits template instances in each
translation unit that uses them, and the linker collapses them together. The advantage
of this model is that the linker only has to consider the object files themselves; there
is no external complexity to worry about. This disadvantage is that compilation time is
increased because the template code is being compiled repeatedly. Code written for this
model tends to include definitions of all templates in the header file, since they must
be seen to be instantiated.

Inline member functions in C++

ISO C++ says that the inline definition of member function in C++ is the same as declaring it with inline. This means that the function will be defined in every compilation unit the member function is used. However, if the function call cannot be inlined for whatever reason, the function is to be instantiated "as usual". (http://msdn.microsoft.com/en-us/library/z8y1yy88%28VS.71%29.aspx) The problem I have with this definition is that it does not tell in which translation unit it would be instantiated.
The problem I encountered is that when facing two object files in a single static library, both of which have the reference to some inline member function which cannot be inlined, the linker might "pick" an arbitrary object file as a source for the definition. This particular choice might introduce unneeded dependencies. (among other things)
For instance:
In a static library
A.h:
class A{
public:
virtual bool foo() { return true; }
};
U1.cpp:
A a1;
U2.cpp:
A a2;
and lots of dependencies
In another project
main.cpp:
#include "A.h"
int main(){
A a;
a.foo();
return 0;
}
The second project refers the first. How do I know which definition the compiler will use, and, consequently which object files with their dependencies will be linked in? Is there anything the standard says on that matter? (Tried, but failed to find that)
Thanks
Edit: since I've seen some people misunderstand what the question is, I'd like to emphasize: If the compiler decided to create a symbol for that function (and in this case, it will, because of 'virtualness', there will be several (externally-seen) instantiations in different object file, which definition (from which object file?) will the linker choose?)
Just my two cents. This is not about virtual function in particular, but about inline and member-functions generally. Maybe it is useful.
C++
As far as Standard C++ is concerned, a inline function must be defined in every translation unit in which it is used. And an non-static inline function will have the same static variables in every translation unit and the same address. The compiler/linker will have to merge the multiple definitions into one function to achieve this. So, always place the definition of an inline function into the header - or place no declaration of it into the header if you define it only in the implementation file (".cpp") (for a non-member function), because if you would, and someone used it, you would get a linker error about an undefined function or something similar.
This is different from non-inline functions which must be defined only once in an entire program (one-definition-rule). For inline functions, multiple definitions as outlined above are rather the normal case. And this is independent on whether the call is atually inlined or not. The rules about inline functions still matter. Whether the Microsoft compiler adheres to those rules or not - i can't tell you. If it adheres to the Standard in that regard, then it will. However, i could imagine some combination using virtual, dlls and different TUs could be problematic. I've never tested it but i believe there are no problems.
For member-functions, if you define your function in the class, it is implicitly inline. And because it appears in the header, the rule that it has to be defined in every translation unit in which it is used is automatically satisfied. However, if you define the function out-of-class and in a header file (for example because there is a circular dependency with code in between), then that definition has to be inline if you include the corresponding file more than once, to avoid multiple-definition errors thrown by the linker. Example of a file f.h:
struct f {
// inline required here or before the definition below
inline void g();
};
void f::g() { ... }
This would have the same effect as placing the definition straight into the class definition.
C99
Note that the rules about inline functions are more complicated for C99 than for C++. Here, an inline function can be defined as an inline definition, of which can exist more than one in the entire program. But if such a (inline-) definition is used (e.g if it is called), then there must be also exactly one external definition in the entire program contained in another translation unit. Rationale for this (quoting from a PDF explaining the rationale behind several C99 features):
Inlining in C99 does extend the C++ specification in two ways. First, if a function is declared inline in one translation unit, it need not be declared inline in every other translation unit. This allows, for example, a library function that is to be inlined within the library but available only through an external definition elsewhere. The alternative of using a wrapper function for the external function requires an additional name; and it may also adversely impact performance if a translator does not actually do inline substitution.
Second, the requirement that all definitions of an inline function be "exactly the same" is replaced by the requirement that the behavior of the program should not depend on whether a call is implemented with a visible inline definition, or the external definition, of a function. This allows an inline definition to be specialized for its use within a particular translation unit. For example, the external definition of a library function might include some argument validation that is not needed for calls made from other functions in the same library. These extensions do offer some advantages; and programmers who are concerned about compatibility can simply abide by the stricter C++ rules.
Why do i include C99 into here? Because i know that the Microsoft compiler supports some stuff of C99. So in those MSDN pages, some stuff may come from C99 too - haven't figured anything in particular though. One should be careful when reading it and when applying those techniques to ones own C++ code intended to be portable C++. Probably informing which parts are C99 specific, and which not.
A good place to test small C++ snippets for Standard conformance is the comeau online compiler. If it gets rejected, one can be pretty sure it is not strictly Standard conforming.
When you have an inline method that is forced to be non-inlined by the compiler, it will really instantiate the method in every compiled unit that uses it. Today most compilers are smart enough to instantiate a method only if needed (if used) so merely including the header file will not force instantiation. The linker, as you said, will pick one of the instantiations to include in the executable file - but keep in mind that the record inside the object module is of a special kind (for instance, a COMDEF) in order to give the linker enough information to know how to discard duplicated instances. These records will not, therefore, result in unwanted dependencies between modules, because the linker will use them with less priority than "regular" records to resolve dependencies.
In the example you gave, you really don't know, but it doesn't matter. The linker won't resolve dependencies based on non-inlined instances alone ever. The result (in terms of modules included by the linker) will be as good as if the inline method didn't exist.
AFAIK, there is no standard definition of how and when a C++ compiler will inline a function call. These are usually "recommendations" that the compiler is in no way required to follow. In fact, different users may want different behaviors. One user may care about speed, while another may care about small generated object file size. In addition, compilers and platforms are different. Some compilers may apply smarter analysis, some may not. Some compilers may generate longer code from the inline, or work on a platform where calls are too expensive, etc.
When you have an inline function, the compiler should still generate a symbol for it and eventually resolve a single version of it. So that if it is in a static library, people can still call the function not in inline. In other words, it still acts as a normal function,.
The only effect of the inline is that some cases, the compiler will see the call, see the inline, and skip the call completely, but the function should still be there, it's just not getting called in this case.
If the compiler decided to create a symbol for that function (and in this case, it will, because of 'virtualness', there will be several (externally-seen) instantiations in different object file, which definition (from which object file?) will the linker choose?)
The definition that is present in the corresponding translation unit. And a translation unit cannot, and I repeat, cannot have but exactly one such definition. The standard is clear about that.
[...]the linker might "pick" an arbitrary object file as a source for the definition.
EDIT: To avoid any further misunderstanding, let me make my point clear: As per my reading of the standard, the ability to have multiple definition across different TUs does not give us any practical leverage. By practical, I mean having even slightly varying implementations. Now, if all your TUs have the exact same definition, why bother which TU the definition is being picked up from?
If you browse through the standard you will find the One Definition Rule is applied everywhere. Even though it is allowed to have multiple definitions of an inline function:
3.2 One Definition Rule:
5 There can be more than one definition of a class type (Clause 9), concept (14.9), concept map (14.9.2), enumeration type (7.2), inline function with external linkage (7.1.2), [...]
Read it in conjunction with
3 [...] An inline function shall be defined in every translation unit in which it is used.
This means that the function will be defined in every compilation unit [...]
and
7.1.2 Function Specifiers
2 A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules
for inline functions defined by 7.1.2 shall still be respected.
3 A function defined within a class definition is an inline function. The inline specifier shall not appear on a block scope function declaration.[footnote: 82] If the inline specifier is used in a friend declaration, that declaration shall be a definition or the function shall have previously been declared inline.
and the footnote:
82) The inline keyword has no effect on the linkage of a function.
§ 7.1.2 138
as well as:
4 An inline function shall be defined in every translation unit in which it is used and shall have exactly the same definition in every case (3.2). [ Note: a call to the inline function may be encountered before its definition appears in the translation unit. —end note ] If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is
declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An inline function with external linkage shall have the same address in all translation units. A static local variable in an extern inline function always refers to the same object. A string literal in the body of an extern inline function is the same object in different translation units. [ Note: A string literal appearing in a default argument expression is not in the body of an inline function merely because the expression is used in a function call from that inline function. —end note ]
Distilled: Its ok to have multiple definitions, but they must have the same look and feel in every translation unit and address -- but that doesn't really give you much to cheer about. Having multiple deinition across translation units is therefore not defined (note: I am not saying you are invoking UB, yet).
As for the virtual thingy -- there won't be any inlining. Period.
The standard says:
The same declaration must be available
There must be one definition
From MSDN:
A given inline member function must be declared the same way in every compilation unit. This constraint causes inline functions to behave as if they were instantiated functions. Additionally, there must be exactly one definition of an inline function.
Your A.h contains the class definition and the member foo()'s definition.
U1.cpp and U2.cpp both define two different objects of class A.
You create another A object in main(). This is just fine.
So far, I have seen only one definition of A::foo() which is inline. (Remember that a function defined within the class declaration is always inlined whether or not it is preceded by the inline keyword.)
Don't inline your functions if you want to ensure they get compiled into a specific library.