I wrote a very simple c++ code, where I defined a function called sqrt which just calls
std::sqrt. Unexpectedly, I got a segmentation fault. The problem doesn't exist if I rename
the function sqrt as something else. However, I can not see any naming conflict since
the sqrt function I defined is not in the namespace std so the two should be perfectly
separated. So what is the real cause of the problem? Thanks!
#include<iostream>
#include<cmath>
double sqrt(double d);
double sqrt(double d) {
return std::sqrt(d);
}
int main() {
double x = 3.0;
std::cout << "The square root of " << x << " is " << sqrt(x) << '\n';
return 0;
}
<cmath> is a funny header. It is allowed to (but not required to) make ::sqrt and
std::sqrt synonyms. If you include it, it's best to assume
that both are present (or just include <math.h>, in which
case, ::sqrt is all that you should get). What's probably
happening in your case is that 1) std::sqrt is in fact a
synonym (via using) for ::sqrt, and 2) the linker is picking
up your ::sqrt first, so you end up with endless recursion.
The only solution, short of changing the name, is to put your
sqrt in a namespace.
EDIT:
Just to be clear: the above is C++11. Earlier versions of C++ did not allow <cmath> to introduce anything into global namespace. All implementations did, however, so the standard was changed to bless the practice. (I guess that's one way of getting compilers to be standard compliant.)
EDIT:
Some additional information as to how a library "picks up"
symbols, in response to the question in comments. Formally,
according to the C++ standard, you may not have two definitions
of the same function (same name, namespace and argument types)
in a program. If the two definitions are in separate
translation units, the behavior is undefine. With this in mind,
there are several practical considerations.
The first can be considered the definition of a library (or at
least the traditional definition). A library is a set of
modules—translation units, in terms of the standard.
(Generally, but not always, the modules consist of compiled
object files.) Linking in a library, however, does not bring
in all of the modules in it; a module from a library is
incorporated into your program only if it resolves an unresolved
external. Thus, if ::sqrt is already defined (resolved)
before the linker looks at the library, the module containing
::sqrt in the library will not become part of your program.
In practice, the term library has been abused in recent years,
to the point where one might say that its meaning has changed.
In particular, what Microsoft calls "dynamically loaded
libraries" (and what were called "shared objects" in Unix, long
before), are not libraries in the traditional sense, and the
above doesn't apply to them. Other issues do, however,
depending on how the dynamic loader works. In the case of Unix,
if several shared objects have the same symbol, all will resolve
to the first one loaded (by default—this can be controlled
by options passed to dlopen). In the case of Windows, by
default, a symbol will be resolved within the DLL if possible;
in your case, if std::sqrt is an inline function, or is
specified as using ::sqrt, this will be the DLL which calls
std::sqrt; if in the header, it is __declspec(dllexport),
this will be the DLL that contains the implementation of
std::sqrt.
Finally, almost all linkers today support some form of weak
references. This is usually used for template instantiations:
something like std::vector<int>::vector( size_t, int ) will be
instantiated in every translation unit which uses it, but as
a "weak" symbol. The linker then chooses one (probably the
first it encounters, but it's not specified), and throws out all
of the others. While this technique is mainly used for template
instantiations, a compiler can define any function using weak
references (and will do so if the function is inline). In this
case, if the definitions are different (as in your case of
::sqrt), then we can truly say that the program is illegal,
since it violates the one definition rule. But the results are
undefined behavior, and don't require a diagnostic. It you
define an inline function or a function template differently in
two different translation units, for example, you will almost
never get an error; if the compiler doesn't actually inline
them, the linker will choose one, and use it in both translation
units. In your case (::sqrt), I doubt that this applies;
I would expect this to be a real library function, and not
inlined. (If it were inlined, the definition would be in the
header <cmath>, and you'd get a duplicate definition error,
since both definitions would be in the same translation unit.)
The problem seems to be that <cmath> is bringing in the sqrt name (without the std:: namespace), as well as std::sqrt. I am afraid you need to use another name.
See this example, using a snapshot of GCC 4.8:
#include<iostream>
#include<cmath>
int main() {
double x = 9.0;
std::cout << sqrt(x) << '\n'; // look, no std::sqrt
}
Per Paragraph 17.6.1.2/4:
Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same
as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode
TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for
names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is
unspecified whether these names are first declared within the global namespace scope and are then injected
into namespace std by explicit using-declarations (7.3.3).
Also, per Annex D.5/2:
Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard
library namespace by the corresponding cname header is placed within the global namespace scope. It is
unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace
std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
Since the exact technique to be used for making global functions available is left up to implementations, your implementation is probably having a using directive such as the one below inside the std namespace:
namespace std
{
using ::sqrt;
// ...
}
Which means that std::sqrt actually becomes an alias for ::sqrt, and you are providing a definition of ::sqrt which effectively ends up calling itself recursively.
The only solution is then to pick a different name.
Related
When using a header which has a format <cname>, an implementation will put names into std namespace. And it may put names into the global namespace as well, as it is described here:
[ Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. [...] — end example ]
Is there a (maybe compiler dependent) way to circumvent/disable this behavior (I'm open to any tricky solution)? I'd like to use names from std only, and I'd like to have an error/warning when using names from the global namespace:
#include <cmath>
double a = cos(0.5); // I'd like to have an error here, because std:: is missing
The reasons:
It is hard to write a portable code, if it may use names from the global namespace, as these names may be not available in other compilers. It is much cleaner to use everything from std, and not use the global namespace at all
cos(0.5f) does a different thing whether std:: is prefixed or not (float vs double result).
Since tricky solutions are fine...
Use a C++ parser, e.g. Clang, and write a tool that parses the header file, collects all the function definitions, and then compares that set against all definitions and calls to global functions.
Of course, it will also pick up cases where someone has defined or called a function with the same name as the standard ones, but you will probably want to avoid that as well anyway.
#include <cmath>
double log(double) {return 1.0;}
int main() {
log(1.0);
}
Suppose the function log() in <cmath> is declared in global namespace (this is unspecified in fact, and we just make this assumption), then it refers to the same function as the log() function we defined.
So does this code violate the one-definition rule (see here, since no diagnostic required, this code may compile in some compiler and we cannot assert if it is correct)?
Note: After recent edits, this is not a duplicate of: What exactly is One Definition Rule in C++?
Typical scenario.
If extern "C" double log(double) is initially declared in the global namespace, then you have redeclared it and provided a definition. The implementation's previous mention of extern "C" carries over to your matching redeclaration. Your definition applies to the function belonging to the implementation, and it is an ODR violation.
As for the manifestation of UB: It's apparently common to treat log as a weak linker symbol. Your implementation overrides libc.so according to ABI rules.
(If the implementation doesn't do extern "C", it's still basically all the same.)
Other likely scenario.
If log is declared in namespace std and then brought into the global namespace, then your declaration will conflict with it. (Actually, a using declaration is technically a declaration.) This error is diagnosed.
Assumption-violating scenario.
then it refers to the same function as the log function we defined
One way for the implementation to put <cmath> names into the global namespace would be to declare extern "C" functions inside namespace std, then do using namespace std, and to ensure that this always happens as the first thing when any standard header is included. Since using namespace isn't "sticky" — it only applies to preceding declarations in the nominated namespace — the rest of the standard library would not be made visible. (This would not declare the names in the global namespace, but the standard only says "placed within the global namespace scope.")
In such an implementation, your declaration would hide the standard one and declare a new function with a new mangled name (say _Z3logd instead of simply log) and a new fully-qualified name (::log instead of ::std::log). Then there would be no ODR violation (unless some inline function uses one log in one TU and the other in a different TU).
The following addresses a previous revision of the OP. I leave it here in case future readers come here with a similar query.
I guess that two names refer to the same entity if and only if they have the same declarative region, where the concept "declarative region" is defined in the standard [...] Is this guess correct? Is there any word in the standard supporting this?
It's called variable hiding or shadowing colloquially. And the standard says what you said almost verbatim. §3.3.10 ¶1 in the current C++17 standard draft:
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class
So does this code violate the one-definition rule (see here, since no diagnostic required, this code may compile in some compiler and we cannot assert it is correct)?
I won't expect it to. The standard requires that all cheader headers (and in particular cmath) introduce their symbols in the std namespace. An implementation that also pours it into the global namespace is standard conforming (since the standard leaves that bit as unspecified), but I would find in bad form. You are correct that it could happen. Now if you were to include math.h (against sage advice) then that would definitely result in a violation of the one definition rule.
Beware. The ODR only concerns definitions that will be included in the resulting program. That means that is does not concern symbols that could be present in libraries, because a (normal) linker does not load the whole libraries, but only the parts that are required to resolve symbols. For example in this code:
#include <cmath>
double log(double) {return 1.0;}
int main()
{
log(1.0);
}
There is no violation of the ODR:
either the log symbol from the C standard library was only included in the std namespace and there is no collision at all
or it is also included in global namespace
In latter case, the declaration double log(double) does not conflict with the one from cmath because it is the same. And as the symbol log is already defined, its definition from the standard library will not be included in the program. As such, only one definition for the log function exists in the program, that one: double log(double) {return 1.0;}.
Things would be different if you extracted the object module containing log from the math library and explicitely link it in your program. Because object modules are always included in the resulting program whereas object modules in libraries are only conditionaly included if they resolve undefined symbols.
References from standard:
Draft n3337 for C++11 or n4296 for C++14 (or n4618 for last revision) are explicit in paragraph 2.2 Phases of translation [lex.phases]:
§9. All external entity references are resolved. Library components are linked to satisfy external references
to entities not defined in the current translation. All such translator output is collected into a program
image which contains information needed for execution in its execution environment.
As shown code uses only one translation unit and as log is already defined in it, the definition from the library will not be used.
I am using only header files specific to C++ (e.g. <cstdlib>), however I still get globally-declared functions, and not just functions in the std namespace. Is there a way, perhaps a compiler switch, to prevent that?
For example, the following code:
#include <cstdlib>
float random() { return 0.0f; }
int main() { return 0; }
Fails to compile under linux, with the following error:
> g++ -c main.cpp main.o
main.cpp: In function ‘float random()’:
main.cpp:2:14: error: new declaration ‘float random()’
/usr/include/stdlib.h:327:17: error: ambiguates old declaration ‘long int random()’
or
> clang++ main.cpp -o main.o
main.cpp:2:7: error: functions that differ only in their return type cannot be overloaded
float random() { return 0.0f; }
/usr/include/stdlib.h:327:17: note: previous declaration is here
extern long int random (void) __THROW;
which is caused that stdlib.h "pollutes" the global namespace with its own random function.
Note, that I am not facing these problems when compiling on Windows, using Visual Studio.
<cstdlib> will always populate std namespace, and sometimes define global symbols, while <stdlib.h> will always define global symbols, and sometimes populate std namespace. This varies from implementation to implementation.
The standard writes:
Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
Which means, that the compiler is allowed to put those symbols into global scope and std namespace at the same time.
Therefore, we see no advantages to prefer one header file over the other. Because they are both very likely to pollute the global scope.
However, it is still necessary to use std namespace when #include <cstdlib>, and do not use std when #include <stdlib.h>, to make sure your code can compile for all compiler implementations.
Advice: Do not use names in standard libraries. First, they are not guaranteed to work. (Note: Few compiler implementations actually keep the global scope clean when you #include <csomething>, so never depend on this.) Second, it will confuse code readers and maintainers, because almost everyone will assume standard names are actually standard, no matter where they come from.
You can declare your functions in their own namespaces to prevent declaration collision.
namespace MyFunc
{
float random() { return 0.0f; }
};
In general you should try to avoid redeclaring in the first place.
You can do this by either using namespaces or by splitting up your source into files which can include cstdlib and others which can use a static version of your (name clashing) function.
If this is not an options then go on reading. But be aware that the following might be very platform specific.
By just having a look at my cstdlib and stdlib.h here at my place I noticed that there is a switch by which cstdlib decides if it includes stdlib.h or just declares abort, atext and exit in the std namespace.
Obviously you pull in the stdlib.h branch. Looking further into this file I noticed the macro __BEGIN_NAMESPACE_STD and later on __END_NAMESPACE_STD. Maybe you could use this, but it is (as the name suggests) some implementation internal macro and should not be set directly by you. However, it should be there for some reason so you might have luck with searching for it.
After some more search it turned out that random is one of several functions (and declarations) which are not wrapped into __BEGIN_NAMESPACE_STD. Therefore, this is not a solution to the problem. (I found another macro _GLIBCPP_USE_NAMESPACES which seems to be used internally as well to #define __BEGIN_NAMESPACE_STD namespace std {).
So to sum it up: This is no viable path and you should use one of the described workarounds.
The standard explicitly permits <c???> headers to bring names of C standard functions to the global namespace.
usually I would prefer to keep your function names different from what is defined as a standard .
For ex here one could use function name as myRandom instead of random so that I can inform the people , who would be maintaining my code later on , that the function being used is NOT the one defined as a standard.
I've heard it asserted that the use of unnamed namespaces in C++ to define functions and ensure that they cannot be called from outside the compilation unit in which they are defined is not good in very large code environments because they cause the symbol table to grow unnecessarily large by including entries to these symbols in the automatically generated namespaces that the C++ compiler provides when unnamed.
namespace {
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
void functionPerhapsInsertedIntoSymbolTable() {
return;
}
}
This is perhaps given that the above is supposed to be the same as doing the following:
namespace randomlyGenerateNameHereNotCollidingWithAnyExistingNames {
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
void functionPerhapsInsertedIntoSymbolTable() {
return;
}
}
using randomlyGenerateNameHereNotCollidingWithAnyExistingNames;
However, is it really that simple, is the compiler required to make a symbol table entry for symbols in the generated namespace name?
Instead, in such situations, I heard it suggested to use a static declaration:
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
static void functionNotInsertedIntoSymbolTable() {
return;
}
Is it true that using a static declaration before a function instead of placing it in an unnamed namespace has the same effect of making the function inaccessible outside the compilation unit in which it is defined? Is there any difference between these two approaches other than potentially not causing the symbol table to grow?
Is the issue with symbol table bloat due to unnamed namespaces just a bug in some implementations of C++ or is the compiler somehow required by the standard to create entries for such functions? If this bloat is considered a bug, are there known compilers for which this is not an issue?
Is it true that using a static declaration before a function instead of placing it in an unnamed namespace has the same effect of making the function inaccessible outside the compilation unit in which it is defined?
Yes.
Namespace-static was deprecated in C++03 in favour of unnamed namespaces, but in fact un-deprecated for C++11 when everybody realised that they are just the same thing and there was no purpose to the deprecation.
Is there any difference between these two approaches
No, not really. There may be some minor subtleties with name lookup due to the use of a namespace, but I can't think of any right now.
other than potentially not causing the symbol table to grow?
Since this is a language-lawyer question with no evident practical problem to solve, I am obliged to point out that the C++ language has no concept of a symbol table, and thus no indication of this effect.
It's also not going to have any noticeable effect until you have tens of thousands of unnamed namespaces; do you?
The reason for the unnamed namespace and deprecation of namespace level static is the ill-fated export keyword.
Everything an exported template relies on has to be link-accessible at the points of instantiation, which are most likely in different source files. The unnamed namespace allowed the 'privatization' aspect of static while still preserving linkage for exported templates.
Now that export has been removed in C++2011, I'm pretty sure the external linkage requirement for the unnamed namespace has been removed, and it now behaves exactly like namespace level static. Someone more familiar with the standard can confirm/refute this.
So this is something that I've always wondered but was never quite sure about. So it is strictly a matter of curiosity, not a real problem.
As far as I understand, whenyou do something like #include <cstdlib> everything (except macros of course) are declared in the std:: namespace. Every implementation that I've ever seen does this by doing something like the following:
#include <stdlib.h>
namespace std {
using ::abort;
// etc....
}
Which of course has the effect of things being in both the global namespace and std. Is this behavior guaranteed? Or is it possible that an implementation could put these things in std but not in the global namespace? The only way I can think of to do that would be to have your libstdc++ implement every c function itself placing them in std directly instead of just including the existing libc headers (because there is no mechanism to remove something from a namespace). Which is of course a lot of effort with little to no benefit.
The essence of my question is, is the following program strictly conforming and guaranteed to work?
#include <cstdio>
int main() {
::printf("hello world\n");
}
EDIT: The closest I've found is this (17.4.1.2p4):
Except as noted in clauses 18 through
27, the contents of each header cname
shall be the same as that of the
corresponding header name.h, as
specified in ISO/IEC 9899:1990
Programming Languages C (Clause 7), or
ISO/IEC:1990 Programming Languages—C
AMENDMENT 1: C Integrity, (Clause 7),
as appropriate, as if by inclusion. In
the C + + Standard Library, however,
the declarations and definitions
(except for names which are defined as
macros in C) are within namespace
scope (3.3.5) of the namespace std.
which to be honest I could interpret either way. "the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C" tells me that they may be required in the global namespace, but "In the C + + Standard Library, however, the declarations and definitions (except for names
which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std." says they are in std (but doesn't specify any other scoped they are in).
Here's a nice synopsis of the situation (with some reality vs. what the standard says) from Stephan T. Lavavej of the MSVC team (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):
> also, <cstddef>, <cstdlib>, and std::size_t etc should be used!
I used to be very careful about that. C++98 had a splendid dream wherein <cfoo> would declare everything within namespace std, and <foo.h> would include <cfoo> and then drag everything into the global namespace with using-declarations. (This is D.5 [depr.c.headers].)
This was ignored by lots of implementers (some of which had very little control over the C Standard Library headers). So, C++0x has been changed to match reality. As of the N2723 Working Paper, http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf , now <cfoo> is guaranteed to declare everything within namespace std, and may or may not declare things within the global namespace. <foo.h> is the opposite: it is guaranteed to declare everything within the global namespace, and may or may not declare things within namespace std.
In reality and in C++0x, including <cfoo> is no safeguard against everything getting declared in the global namespace anyways. That's why I'm ceasing to bother with <cfoo>.
This was Library Issue 456, http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 .
(C++0x still deprecates the <foo.h> headers from the C Standard Library, which is hilarious.)
I've never been fond of the <cfoo> headers myself, and found that I've always use <foo.h>. Now I feel like I can stop being anxious about my lack of C++ 'purity' in that regard.
At the present time, no. In fact, even though the code will work with every compiler I now of, it's really not supposed to work at all -- #includeing one of the c* headers is only supposed to give you access to the names inside of namespace std.
Since implementation of this was such a pain (getting it right essentially required duplicating the entire C library as a C++ library in the right namespace), in C++ 0x they've changed the requirements a bit -- your code is now allowed to work, though (at least if memory serves) it's still not required to work.
I cannot speak for the standards, as I have not read them, but one could envision a C++ environment that is not built on top of a C environment, or where the C environment is a compatibility layer on top of underlying C++ APIs. In such a case, these guarantees may not be made. I would be surprised if such an implementation would be prohibited from being a compliant implementation.