Situation as follows:
in a codebase a header which defines some types, mostly convinient shortcuts like u64 for uint64_t exists. These definitions are global, as general type definitions do not really make sense when encapsulated in a namespace. This header is used in almost any other file to unify the codebase.
Also a public availible header only library is used, which happens to define the same name. In fact the other definition is not a type but a parameter name like:
void function(uint64_t u64);
Now the compiler throws warnings about that the parameter name shadows the global type definition. Which is correct in some respect.
But as the common global type-management header is needed and the include for the library is also needed, my question is how to resolve that problem in a sane way.
Also, why a type name can be shadowed by a function parameter/argument name, as a variable name and a typename are two very different things. That sounds more like a bug in the compiler to me. Without having sound knowlege about the standard in that topic, I would assume
using mytype = unsigned int;
void myfunc(mytype mytype);
to be valid, as I just have defined a variable to have the same name as a type, but the compiler can always distinguish both, because of the syntax.
Additional Question:
why the include order of both headers seems to have no effect.
I tried to solve the problem by including the external library header first (so the global type shortcut should not exist in that module) and included the common global header which defines the types later. But the Warnings persist.
Edited to preceise the problem (2 times)
But as the common global type-management header is needed and the include for the library is also needed, my question is how to resolve that problem in a sane way.
One thing you could do is to isolate the code that utilized the headers that produce that error and move it into its own compilation unit for which you silent that shadowing error message.
Also, why a type name can be shadowed by a function parameter/argument name, as a variable name and a typename are two very different things.
They are two different things, but there are cases where the syntax for both would be the same, so the compiler has to decide whether to use the parameter or the type.
Here one example, with static_assert, might be odd, but maybe there are other situations where this can be actually hard to debug:
#include <utility>
struct Type {
constexpr bool operator == (int i) {
return i==102;
}
};
template <typename X>
constexpr void f1(X Type) {
// does not fail because lambda is called which returns 101
static_assert(Type() == 101, "");
}
void f2() {
// fails because the operator == checks against 102
static_assert(Type() == 101, "");
}
int main() {
f1([] { return 101; });
f2();
return 0;
}
Here is probably a better example, maybe still an odd one but I could imagine that this one is more likely to occur:
bar(TypeA()); would not construct TypeA directly but TypeA operator () is called on the object of type TypeB:
#include <utility>
struct TypeA {
void operator () () {
}
};
struct TypeB {
TypeA operator () () {
return TypeA();
}
};
void bar(TypeA a) {
}
void foo(TypeB TypeA ) {
bar(TypeA());
}
int main() {
foo(TypeB());
}
Related
I have some C++ code that is automatically generated to wrap some C code.
The C code has a predictable structure with the exception that it has/has not a certain function.
Since the C++ code is derived from a description that does not have this information. I would like to use the template processor to decide if this function can be called.
small example:
struct SomeStruct{
int indicatorMember;
};
extern "C" void someFun(struct SomeStruct* somePointer){
}
void someCPPcode(){
SomeStruct s;
// do something
someMechanismToCall_someFunIfExists(&s);
// do something other
}
How does someMechanismToCall_someFunIfExists have to look like, so that someCPPcode can be compiled/run in cases there someFun does exist and if it does not exist?
Is this even possible?
It would also be possible to decide if this function exists, if a certain member is part of a structure.
so, if indicatorMember does exist, the function also exists.
You might use overload with lower priority to solve your issue:
// "C-Header"
struct SomeStruct
{
int indicatorMember;
};
// Present or not
extern "C" void someFun(struct SomeStruct* somePointer){
}
// Fallback
void someFun(...) { /*Empty*/ }
void someCPPcode()
{
SomeStruct s;
// do something
someFun(&s);
// do something other
}
it would also be possible to decide if this function exists, if a certain member is part of a structure. so, if indicatorMember does exist, the function also exists.
There are several ways to detect presence of member, such as use of std::experimental::is_detected.
but outside template, you still have issue:
decltype(auto) someFunIfExists([[maybe_unused]] SomeStruct* p)
{
if constexpr (has_someFunc<SomeStruct>::value) {
return someFun(p); // Not discarded as you might expect -> Error
}
}
as if constexpr (false) { static_assert(false); } is invalid).
So you have to wrap the function inside template:
template <typename T>
decltype(auto) someFunIfExists([[maybe_unused]] T* p)
{
if constexpr (has_someFunc<T>::value) {
return someFun(p);
}
}
void someCPPcode(){
SomeStruct s;
// do something
someFunIfExists(&s);
// do something other
}
The question of whether there's a definition of some symbol with external linkage or not is inherently a question that can only be answered during linking. There is no way for the compiler to know during compilation of an individual C++ source file whether there is going to be a definition of some external function somewhere else. SFINAE can, in the best case, check for whether a certain function is declared. It is impossible for SFINAE to determine whether the linker will find a definition of that function later on.
If the C library comes with headers that you can include in C++ and that declare the functions in question only if the particular version of the C library defines them, you can use an appraoch like the one described in Jarod42's answer.
Otherwise, the best thing I can think of to do here would be to define default implementations of your functions as weak symbols that are always defined, e.g.:
struct SomeStruct
{
int indicatorMember;
};
extern "C" void someFun(SomeStruct* somePointer) __attribute__((weak))
{
// do whatever this should do in case the C library does not define this function
}
Weak symbols are no part of Standard C++, so the exact mechanism for doing this depends on your compiler and platform. The above would be an example for GCC. MSVC has an undocumented linker flag /alternatename that allows to provide default definitions for a symbol, see this answer.
During linking, if the linker finds a non-weak definition of the same symbol coming from your C library, it will pick that one, otherwise it will pick your default implementation…
I have a big project and work on refactoring it. Major task is rewrite of logger. New logger is (as far as I can tell) API-compatible with old one, so I believed that after changing header include directory, recompile and relink everything should work. But no. I get multiple errors of the kind undefined reference to <static_data_member>. I can't paste actual code, but it looks for example like this:
// Foo.h
class Foo {
static const int bar = 0;
int baz; // assigned in c-tor
void updateBaz() { baz = bar; }
// ....
}
static const int bar is NOT defined in Foo.cpp. It is sometimes printed by log macros. And it used to work (with old logger), now I have to define it. What change could have caused it?
Another example that that occurs with variables declared by boost:
(...)/blog_adaptor.h:50: error: undefined reference to bbost::serialization::version<CA::CReyzinSignature>::value'
So: when are definitions to static members required and when can they be omitted?
Unless the variables are declared inline (a C++17 feature), definitions of static member variables are not optional, as far as the C++ standard is concerned. Failure to provide a definition is undefined behavior.
Compilers and linkers may vary on exactly what will make them check to see if definitions exist, but that is the nature of undefined behavior.
As Nicol Bolas answered, the code in my project had undefined behavior because static data members were initialized but nowhere defined. To summarize and extend:
Static data member doesn't need to be defined when:
It is not used or is used only in discarded branches (non-instantiated templates and discarded branches of constexpr-if)
in C++17 if member is inline
also clang-tidy says that "out-of-line definition of constexpr static data member is redundant in C++17 and is deprecated", so probably static constexpr also doesn't need it
Further, following code shows why my bad project was not triggering linker error before. I don't know whether it is "not odr-use" or "Undefined Behavior that doesn't hurt you yet":
#include <boost/serialization/version.hpp>
class Klass {};
//BOOST_CLASS_VERSION(Klass, 3);
// would be expanded to:
namespace boost { namespace serialization {
template<>
struct version<Klass> {
static const int value = 3; // not defined anywhere
};
} }
int foo (int val) { // was used by old logger
return val;
}
int bar (const int &val) { // is used by new logger
return val;
}
int main () {
// return bar(boost::serialization::version<Klass>::value); // link error
return foo(boost::serialization::version<Klass>::value); // works fine
}
So there is no link error if member is used but not it's address is not queried. Passing value by reference qualifies as querying the address.
I'd like to check if a fully-qualified name and an unqualified or partly-qualified name refer to the same symbol, even if one name isn't defined. That is, I'd like to be able to write something like this as part of a refactoring tool:
namespace A {
void f() {};
}
namespace B {
namespace A {};
bool g() {
// returns false
return is_same_symbol<A::f, ::A::f>::value;
}
}
namespace C {
bool h() {
// returns true
return is_same_symbol<A::f, ::A::f>::value;
}
}
You clarify in a comment:
I'm trying to figure out the correct SFINAE incantation for this to check if a free function of a given name exists.
You can't.
When you say a free function called foo exists, what do you mean?
It has to be one of:
The compiler has seen a declaration of foo:
... int foo(int i);
or:
The compiler has seen a definition of foo:
... int foo(int i) {
...
return ...;
}
A definition is also a declaration, so if the compiler has not
seen a declaration of foo then it hasn't seen a definition either.
Suppose you're trying to SFINAE-probe whether foo is declared.
If the compiler has not even seen a declaration of foo then any
subsequent code you write that uses foo as a name will provoke
a compile error in the vein:
error: use of undeclared identifier 'foo'
You can't write code to SFINAE-probe whether foo is declared because
you can't write C++ that uses undeclared names, period.
Suppose you're trying to SFINAE-probe whether foo is defined.
To do that, you'd first have to have declaration of foo - either
one you've written yourself or one that you've got from some header file.
But of course, given a declaration of foo, the compiler can't tell whether
or not it is defined and doesn't care, except in the special cases that the function
is declared as static or inline or in an anonymous namespace.
Otherwise, it leaves the finding or not finding of a definition to the linker.
Generally then, SFINAE-probing the existence of function definitions is likewise
a non-starter. And even if foo is declared static
or inline or in an anonymous namespace, and lacks a definition within the compilation unit, any
code that uses foo in conformity with its declaration remains well-formed
code; so even in those cases SFINAE-probing for is-it-defined remains meaningless.
Warning, C++ hating ahead...
I have seen here slightly different variations of this issue, here is my take
namespace space {
}
template <typename T> struct C
{
void foo() {
using namespace space;
bar(t);
}
T t;
};
class A {
};
namespace space {
void bar(const A& a){
}
}
int main()
{
C<A> c;
c.foo();
return 0;
}
if bar is not inside a namespace, everything compiles ok. Putting a namespace breaks compilation with gcc. What is more interesting - gcc finds the function, but just don't feel like using it:
ConsoleApplication1.cpp: In instantiation of 'void C<T>::foo() [with T = A]':
ConsoleApplication1.cpp:26:10: required from here
ConsoleApplication1.cpp:8:8: error: 'bar' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point
instantiation [-fpermissive]
bar(t);
^
ConsoleApplication1.cpp:18:6: note: 'void space::bar(const A&)' declared here, later in the translation unit
void bar(const A& a){
Is there any sane reason for this behaviour, except that the standard says so? And is there any switch I can make gcc accept this code, since it seems there is no technical issue, and I do not see why such code should not work from a pure language standpoint.
templates are not macros. Name lookup of symbols is done in two contexts: first, where you wrote the template, and second pass of only argument-dependent lookup (ADL, or Koeing Lookup) when you pass the template a type (when the template "factory" is instantiated into an actual class or function).
When the function is in the same namespace as A, it is found via ADL. When it is not, it will not be. So when you moved the bar function into space::bar, it was no longer ADL-found with an argument of type A.
This is intentional, to both prevent your template from meaning completely different things at different spots, and to allow non-member interface extensions to types in their own namespace only.
Either use a traits class, stick such helper functions in the same namespace as the type, or pass in functors.
A traits class is probably easiest. Create a class with a static function foo (if you want a default implementation: otherwise leave empty). Call it from your template. Specialize it for A. Now you can implement special behavior for your A type at that point -- it could even call your space::bar function if that function is in view.
Putting bar in the same namespace as A is another solution, and I find it scales better than traits classes. Many of my personal traits classes end up falling back on an ADL lookup, as that lets me inject the handling code right next to where I define A. (The use of traits classes lets me also have my trait handle things in std, where I am not allowed to inject functions for ADL purposes for types living in std (you can inject ADL functions into std, but only for your own types))
The functor solution is how std::map works -- while it falls back on std::less<T> which falls back on operator<, it takes a functor that lets you specify how the key type should be compared within this map.
Is there any sane reason for this behaviour, except that the standard says so?
Sane or not, C++ usually requires names to be declared before use. You don't declare bar before using it; specifically, using namespace space only imports names that have been declared at that point, and not bar.
(If you care about the reason, it's because C++ inherited its declaration rules from the languages of half a century ago, when computers were somewhat primitive. Rules like this allowed compilation in a single pass, so that the compiler didn't have to keep waiting for the operator to put the stack of punch cards back into the hopper. Or something like that; I'm not quite sure how computers worked back then.)
And is there any switch I can make gcc accept this code
As the error message says, -fpermissive. But your code won't be portable if you don't stick to the standard.
This error has nothing to do with namespaces or templates at all, but is the standard error of using a function before it has been declared. Just as you cannot do:
void caller() { callee(); }
void callee() {}
But must instead do:
void callee() {}
void caller() { callee(); }
Or:
void callee();
void caller() { callee(); }
void callee() {}
... the same applies for more complicated functions involving templates and namespaces. Note that if you reorder slightly, it works just fine:
class A {
};
namespace space {
void bar(const A& a){
}
}
template <typename T> struct C
{
void foo() {
using namespace space;
bar(t);
}
T t;
};
int main()
{
C<A> c;
c.foo();
return 0;
}
I was reading the linked question which leads me to ask this question.
Consider the following code
int main()
{
string SomeString();
}
All says, compiler takes this as a function prototype and not as a string object. Now consider the following code.
int main()
{
string Some()
{
return "";
}
}
Compiler said this is invalid as I guess nested function definition is not allowed. If it is not allowed, why nested function prototypes are allowed? It is not giving any advantage rather than making confusion (or am I missing some valid points here?).
I figured out the following is valid.
int main()
{
string SomeFun();
SomeFun();
return 0;
}
string SomeFun()
{
std::cout << "WOW this is unexpected" << std::endl;
}
This is also confusing. I was expecting the function SomeFun() will have a scope only in main. But I was wrong. Why compiler is allowing to compile code like the above? Is there any real time situations where code like the above makes sense?
Any thoughts?
Your prototype is just 'Forward Declaration'. Please check out the Wikipedia article.
Basically, it tells the compiler "don't be alarmed if the label 'SomeFun' is used in this way". But your linker is what's responsible for finding the correct function body.
You can actually declare a bogus prototype, e.g. 'char SomeFun()' and use it all over your main. You will only get an error when your linker tries to find the body of your bogus function. But your compiler will be cool with it.
There are lots of benefits. You have to remember the function body is not always in the same source code file. It can be in a linked library.Also, that linked library may be have a specific 'link signature'.Use conditional defines you may even select the correct link signature at build time using your scoped prototypes.Although most people would use function pointers for that instead.
Hope this helps.
Just as a side note, C++03 does have a roundabout way of defining local functions. It requires abusing the local-class feature:
int main()
{
struct Local
{
static string Some()
{
return "";
}
};
std::cout << Local::Some() << std::endl;
}
This is a convention from C -- like many -- which C++ has adopted.
The ability to declare a function inside another function in C is a decision that most programmers probably consider regrettable and unnecessary. Particularly with modern OOP design where function definitions are comparatively smaller than they are in C.
If you would like to have functions that only exist in the scope of another function, two options are boost::lambda and C++1x lambda.
As to why your declaration of
void f() {
void g(); g();
}
is better than this one
void g();
void f() {
g();
}
It's generally good if you keep declarations as local as possible, so that as few name clashes as possible result. I say it's arguable whether declaring a function locally (this way) is really fortunate, as i think it's still better to ordinary include its header and then go the "usual" way, which is also less confusing to people not knowing about that. Sometimes, it's also useful to work around a shadowed function
void f() {
int g;
// oops, ::g is shadowed. But we can work around that
{
void g(); g();
}
}
Of course, in C++ we could call function g using its_namespace::g() - but in the old days of C, that wouldn't have been possible, and that thing allowed the programmer to still access the function. Also note that while syntactically it is not the same, semantically the following does also declare a function within a local scope, that actually targets a different scope.
int main() {
using std::exit;
exit();
}
As a side note, there are more situations like that where the target scope of a declaration is not the scope where that declaration appears in. In general, the entity you declare becomes a member of the scope in which the declaration appears. But that's not always the case. Consider for example friend declarations, where that thing happens
struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!
Even though the function declaration (and definition!) of f happened within the scope of X, the entity (the function itself) became a member of the enclosing namespace.
Function prototypes are hints for the compiler. They indicate that the functions are implemented somewhere else, if not already discovered. Nothing more.
When you declare a prototype as you are doing you are basically telling the compiler to wait for the linker to resolve it. Depending where you write the prototype the scoping rules apply. There is nothing technically wrong writing the prototype inside your main() function (although IMHO a bit messier), it just means that the function is only locally known inside the main(). If you would have declared the prototype at the top of your source file (or more commonly in a header file), the prototype/function would be known in the whole source.
string foo()
{
string ret = someString(); // Error
return ret;
}
int main(int argc,char**argv)
{
string someString();
string s = somestring(); // OK
...
}