Define replacement with Constant variable issue - c++

I am creating an component, generalization of a template. For creation must be used string identifier.
I am replacing:
#define MYCOMPONENT_CONSTANT_IDENTIFIER "ID value"
with
namespace myComponent
{
static const QString constant_identifier = "ID value"
}
to follow some codding standards (MISRA,...).
This should work regarding C++. And I checked it up at Constants-only header file C++.
This constant is defined in a header of a component "myComponent" and included in a header where my Indexer is initialized and component is created. This has not been changed at replacement time.
Replacement builds successfully, but fails on attempt to run.
Segmentation fault hapends at:
template<>
inline void TMyIndexer::Init()
{
Map(...)
//before
//Map( ENUM_VAL, QSharedPointer<ITableFieldDefs>(new myComponent::TTableFieldDefs(MYCOMPONENT_CONSTANT_IDENTIFIER)) );
Map( ENUM_VAL, QSharedPointer<ITableFieldDefs>(new myComponent::TTableFieldDefs(myComponent::constant_identifier)) );
Map(...)
}
Where:
// TStaticFieldDefs<> implements ITableFieldDefs
typedef TStaticFieldDefs<myComponent::Fields> TTableFieldDefs;
//constructor
TStaticFieldDefs(QString id) : fId(id) {}
If I go up the the stack:
2.) qstring.h: inline QString::QString(const QString &other) : d(other.d)
{ Q_ASSERT(&other != this); d->ref.ref(); }
1.) qatomic_x86_64.h: inline bool QBasicAtomicInt::ref()
I suppose there something wrong in template generalization, inline definition in the constructor or something else I am not aware.
Any explanation is welcome.
I am out of ideas and am kindly asking for help.

My guess is that you're trying to use your constant object from a static context. A C++ standard states that order of static objects initialization is undefined. So you may reference uninitialized object that may cause a segfault.

Related

Warning unused variable using typeid

I have written a small wrapper for typeinfo to get the typecode of a variable at compile time more easily:
template<typename DataType>
class TypeInfo
{
public:
static const char* typecode()
{
DataType TypedVariable = 0;
const char* code = typeid(TypedVariable).name();
return(code);
};
};
I use it like this:
const char* code = TypeInfo<float>::typecode();
It compiles perfectly fine and works as expected, but I am getting the warning
src/common.hh(153): warning: variable "TypedVariable" was set but never used
detected during:
instantiation of "char TypeInfo<DataType>::typecode() [with DataType=r32]"
...
I am wondering why "calling" typeid() on a variable does not count as using it. I know that it is a defined keyword, but still I am irritated that getting the type of a variable does not count as using it.
The compilation is done using nvcc of CUDA 9.2. Maybe it is a CUDA specific thing?
Thanks for any help :)
//edit:
I made a mistake by not returning the full char* because I use only normal types! Thanks for making me aware of the typo! I also added the template definition. I forgot to copy that over!
Because you don't use the value of TypedVariable. You just use its type (and you can get it's type by rewriting your initialization as:
char const * const code = typeid(DataType).name();

std::experimental::source_location at compile time

std::experimental::source_location will probably be added to the C++ standard at some point. I'm wondering if it possible to get the location information into the compile-time realm. Essentially, I want a function that returns different types when called from different source locations. Something like this, although it doesn't compile because the location object isn't constexpr as it's a function argument:
#include <experimental/source_location>
using namespace std::experimental;
constexpr auto line (const source_location& location = source_location::current())
{
return std::integral_constant<int, location.line()>{};
}
int main()
{
constexpr auto ll = line();
std::cout << ll.value << '\n';
}
This doesn't compile, with a message about
expansion of [...] is not a constant expression
regarding the return std::integral_constant<int, location.line()>{} line. What good it is to have the methods of source_location be constexpr if I can't use them?
As Justin pointed the issue with your code is that function argument are not constexpr but the problem of using source_location in a constexpr function in a more useful way is mentioned in the constexpr! functions proposal which says:
The "Library Fundamentals v. 2" TS contains a "magic" source_location
class get to information similar to the FILE and LINE macros
and the func variable (see N4529 for the current draft, and N4129
for some design notes). Unfortunately, because the "value" of a
source_location is frozen at the point source_location::current() is
invoked, composing code making use of this magic class is tricky:
Typically, a function wanting to track its point of invocation has to
add a defaulted parameter as follows:
void my_log_function(char const *msg,
source_location src_loc
= source_location::current()) {
// ...
}
This idiom ensure that the value of the source_location::current()
invocation is sampled where my_log_function is called instead of where
it is defined.
Immediate (i.e., constexpr!) functions, however, create a clean
separation between the compilation process and the constexpr
evaluation process (see also P0992). Thus, we can make
source_location::current() an immediate function, and wrap it as
needed in other immediate functions: The value produced will
correspond to the source location of the "root" immediate function
call. For example:
constexpr! src_line() {
return source_location::current().line();
}
void some_code() {
std::cout << src_line() << '\n'; // This line number is output.
}
So this is currently an open problem.

Compiling error in trie constructor [duplicate]

This question already has answers here:
Default value of function parameter
(5 answers)
Closed 5 years ago.
What's the place for the default parameter value? Just in function definition, or declaration, or both places?
Default parameter values must appear on the declaration, since that is the only thing that the caller sees.
EDIT: As others point out, you can have the argument on the definition, but I would advise writing all code as if that wasn't true.
You can do either, but never both. Usually you do it at function declaration and then all callers can use that default value. However you can do that at function definition instead and then only those who see the definition will be able to use the default value.
C++ places the default parameter logic in the calling side, this means that if the default value expression cannot be computed from the calling place, then the default value cannot be used.
Other compilation units normally just include the declaration so default value expressions placed in the definition can be used only in the defining compilation unit itself (and after the definition, i.e. after the compiler sees the default value expressions).
The most useful place is in the declaration (.h) so that all users will see it.
Some people like to add the default value expressions in the implementation too (as a comment):
void foo(int x = 42,
int y = 21);
void foo(int x /* = 42 */,
int y /* = 21 */)
{
...
}
However, this means duplication and will add the possibility of having the comment out of sync with the code (what's worse than uncommented code? code with misleading comments!).
Although this is an "old" thread, I still would like to add the following to it:
I've experienced the next case:
In the header file of a class, I had
int SetI2cSlaveAddress( UCHAR addr, bool force );
In the source file of that class, I had
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force = false )
{
...
}
As one can see, I had put the default value of the parameter "force" in the class source file, not in the class header file.
Then I used that function in a derived class as follows (derived class inherited the base class in a public way):
SetI2cSlaveAddress( addr );
assuming it would take the "force" parameter as "false" 'for granted'.
However, the compiler (put in c++11 mode) complained and gave me the following compiler error:
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp: In member function 'void CMax6956Io::Init(unsigned char, unsigned char, unsigned int)':
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: error: no matching function for call to 'CMax6956Io::SetI2cSlaveAddress(unsigned char&)'
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: note: candidate is:
In file included from /home/geertvc/mystuff/domoproject/lib/i2cdevs/../../include/i2cdevs/max6956io.h:35:0,
from /home/geertvc/mystuff/domoproject/lib/i2cdevs/max6956io.cpp:1:
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: int CI2cHal::SetI2cSlaveAddress(unsigned char, bool)
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: candidate expects 2 arguments, 1 provided
make[2]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/max6956io.cpp.o] Error 1
make[1]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/all] Error 2
make: *** [all] Error 2
But when I added the default parameter in the header file of the base class:
int SetI2cSlaveAddress( UCHAR addr, bool force = false );
and removed it from the source file of the base class:
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force )
then the compiler was happy and all code worked as expected (I could give one or two parameters to the function SetI2cSlaveAddress())!
So, not only for the user of a class it's important to put the default value of a parameter in the header file, also compiling and functional wise it apparently seems to be a must!
If the functions are exposed - non-member, public or protected - then the caller should know about them, and the default values must be in the header.
If the functions are private and out-of-line, then it does make sense to put the defaults in the implementation file because that allows changes that don't trigger client recompilation (a sometimes serious issue for low-level libraries shared in enterprise scale development). That said, it is definitely potentially confusing, and there is documentation value in presenting the API in a more intuitive way in the header, so pick your compromise - though consistency's the main thing when there's no compelling reason either way.
One more point I haven't found anyone mentioned:
If you have virtual method, each declaration can have its own default value!
It depends on the interface you are calling which value will be used.
Example on ideone
struct iface
{
virtual void test(int a = 0) { std::cout << a; }
};
struct impl : public iface
{
virtual void test(int a = 5) override { std::cout << a; }
};
int main()
{
impl d;
d.test();
iface* a = &d;
a->test();
}
It prints 50
I strongly discourage you to use it like this
the declaration is generally the most 'useful', but that depends on how you want to use the class.
both is not valid.
Good question...
I find that coders typically use the declaration to declare defaults. I've been held to one way (or warned) or the other too based on the compiler
void testFunct(int nVal1, int nVal2=500);
void testFunct(int nVal1, int nVal2)
{
using namespace std;
cout << nVal1 << << nVal2 << endl;
}
You may do in either (according to standard), but remember, if your code is seeing the declaration without default argument(s) before the definition that contains default argument, then compilation error can come.
For example, if you include header containing function declaration without default argument list, thus compiler will look for that prototype as it is unaware of your default argument values and hence prototype won't match.
If you are putting function with default argument in definition, then include that file but I won't suggest that.
Adding one more point. Function declarations with default argument should be ordered from right to left and from top to bottom.
For example in the below function declaration if you change the declaration order then the compiler gives you a missing default parameter error. Reason the compiler allows you to separate the function declaration with default argument within the same scope but it should be in order from RIGHT to LEFT (default arguments) and from TOP to BOTTOM(order of function declaration default argument).
//declaration
void function(char const *msg, bool three, bool two, bool one = false);
void function(char const *msg, bool three = true, bool two, bool one); // Error
void function(char const *msg, bool three, bool two = true, bool one); // OK
//void function(char const *msg, bool three = true, bool two, bool one); // OK
int main() {
function("Using only one Default Argument", false, true);
function("Using Two Default Arguments", false);
function("Using Three Default Arguments");
return 0;
}
//definition
void function(char const *msg, bool three, bool two, bool one ) {
std::cout<<msg<<" "<<three<<" "<<two<<" "<<one<<std::endl;
}

Insufficient contextual information to determine type

I've done research and I can't make sense of this message at all. Everything I find seems to be a bug with the compiler itself. I've also read somewhere 'insufficient contextual information to determine type' is not a helpful message.
My question: Does anyone have information on what this compile error message means?
I understand this question might be code specific. My code merely declares a global anonymous struct, and then once it tries to access it in a function I get this error (or so I've evaluated it).
EDIT: I got my code to compile! - But I still don't know what the error means, so I'll leave the question open.
EDIT: Here's my code, as far as I'd suppose is important:
typedef ofstream::pos_type ofilepos;
struct stack // stack is my own stack data-structure
{
// ...
// int L; struct N *l;
stack(): L(0), l(NULL) {}
}
// ...
struct
{
const char* zero;
stack<ofilepos> chunks; // it was 'chunks();' with (), and it didn't work
} _fileext = {"\0\0\0"};
// ...
ofstream& write_stack_pushsize(ofstream& f)
{
_fileext.chunks.push(new ofilepos(f.tellp()));
f.write(_fileext.zero,4);
return f;
}
I think it might have been because I was calling a constructor in a struct declaration, rather than later... or something... it could be a bug in C++03.
Regarding this code,
struct
{
const char* zero;
stack<ofilepos> chunks();
} _fileext = {"\0\0\0"};
there is no way to provide a definition of the chunks member function after the anonymous struct definition.
Considering also the following usage example,
ofstream& write_stack_pushsize(ofstream& f)
{
_fileext.chunks.push(new ofilepos(f.tellp()));
f.write(_fileext.zero,4);
return f;
}
apparently you meant to define chunks as a data member instead of as a function member.
By the way, using underscore at the start of a name can possibly conflict with names in the implementation of the standard library. E.g. these names are reserved in the global namespace (if I recall correctly). The usual convention is instead to have an underscore at the end of a name, to signify "member".
To signyfy "global" I simply use a namespace that I call g. :-)

Where to put default parameter value in C++? [duplicate]

This question already has answers here:
Default value of function parameter
(5 answers)
Closed 5 years ago.
What's the place for the default parameter value? Just in function definition, or declaration, or both places?
Default parameter values must appear on the declaration, since that is the only thing that the caller sees.
EDIT: As others point out, you can have the argument on the definition, but I would advise writing all code as if that wasn't true.
You can do either, but never both. Usually you do it at function declaration and then all callers can use that default value. However you can do that at function definition instead and then only those who see the definition will be able to use the default value.
C++ places the default parameter logic in the calling side, this means that if the default value expression cannot be computed from the calling place, then the default value cannot be used.
Other compilation units normally just include the declaration so default value expressions placed in the definition can be used only in the defining compilation unit itself (and after the definition, i.e. after the compiler sees the default value expressions).
The most useful place is in the declaration (.h) so that all users will see it.
Some people like to add the default value expressions in the implementation too (as a comment):
void foo(int x = 42,
int y = 21);
void foo(int x /* = 42 */,
int y /* = 21 */)
{
...
}
However, this means duplication and will add the possibility of having the comment out of sync with the code (what's worse than uncommented code? code with misleading comments!).
Although this is an "old" thread, I still would like to add the following to it:
I've experienced the next case:
In the header file of a class, I had
int SetI2cSlaveAddress( UCHAR addr, bool force );
In the source file of that class, I had
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force = false )
{
...
}
As one can see, I had put the default value of the parameter "force" in the class source file, not in the class header file.
Then I used that function in a derived class as follows (derived class inherited the base class in a public way):
SetI2cSlaveAddress( addr );
assuming it would take the "force" parameter as "false" 'for granted'.
However, the compiler (put in c++11 mode) complained and gave me the following compiler error:
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp: In member function 'void CMax6956Io::Init(unsigned char, unsigned char, unsigned int)':
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: error: no matching function for call to 'CMax6956Io::SetI2cSlaveAddress(unsigned char&)'
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: note: candidate is:
In file included from /home/geertvc/mystuff/domoproject/lib/i2cdevs/../../include/i2cdevs/max6956io.h:35:0,
from /home/geertvc/mystuff/domoproject/lib/i2cdevs/max6956io.cpp:1:
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: int CI2cHal::SetI2cSlaveAddress(unsigned char, bool)
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: candidate expects 2 arguments, 1 provided
make[2]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/max6956io.cpp.o] Error 1
make[1]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/all] Error 2
make: *** [all] Error 2
But when I added the default parameter in the header file of the base class:
int SetI2cSlaveAddress( UCHAR addr, bool force = false );
and removed it from the source file of the base class:
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force )
then the compiler was happy and all code worked as expected (I could give one or two parameters to the function SetI2cSlaveAddress())!
So, not only for the user of a class it's important to put the default value of a parameter in the header file, also compiling and functional wise it apparently seems to be a must!
If the functions are exposed - non-member, public or protected - then the caller should know about them, and the default values must be in the header.
If the functions are private and out-of-line, then it does make sense to put the defaults in the implementation file because that allows changes that don't trigger client recompilation (a sometimes serious issue for low-level libraries shared in enterprise scale development). That said, it is definitely potentially confusing, and there is documentation value in presenting the API in a more intuitive way in the header, so pick your compromise - though consistency's the main thing when there's no compelling reason either way.
One more point I haven't found anyone mentioned:
If you have virtual method, each declaration can have its own default value!
It depends on the interface you are calling which value will be used.
Example on ideone
struct iface
{
virtual void test(int a = 0) { std::cout << a; }
};
struct impl : public iface
{
virtual void test(int a = 5) override { std::cout << a; }
};
int main()
{
impl d;
d.test();
iface* a = &d;
a->test();
}
It prints 50
I strongly discourage you to use it like this
the declaration is generally the most 'useful', but that depends on how you want to use the class.
both is not valid.
Good question...
I find that coders typically use the declaration to declare defaults. I've been held to one way (or warned) or the other too based on the compiler
void testFunct(int nVal1, int nVal2=500);
void testFunct(int nVal1, int nVal2)
{
using namespace std;
cout << nVal1 << << nVal2 << endl;
}
You may do in either (according to standard), but remember, if your code is seeing the declaration without default argument(s) before the definition that contains default argument, then compilation error can come.
For example, if you include header containing function declaration without default argument list, thus compiler will look for that prototype as it is unaware of your default argument values and hence prototype won't match.
If you are putting function with default argument in definition, then include that file but I won't suggest that.
Adding one more point. Function declarations with default argument should be ordered from right to left and from top to bottom.
For example in the below function declaration if you change the declaration order then the compiler gives you a missing default parameter error. Reason the compiler allows you to separate the function declaration with default argument within the same scope but it should be in order from RIGHT to LEFT (default arguments) and from TOP to BOTTOM(order of function declaration default argument).
//declaration
void function(char const *msg, bool three, bool two, bool one = false);
void function(char const *msg, bool three = true, bool two, bool one); // Error
void function(char const *msg, bool three, bool two = true, bool one); // OK
//void function(char const *msg, bool three = true, bool two, bool one); // OK
int main() {
function("Using only one Default Argument", false, true);
function("Using Two Default Arguments", false);
function("Using Three Default Arguments");
return 0;
}
//definition
void function(char const *msg, bool three, bool two, bool one ) {
std::cout<<msg<<" "<<three<<" "<<two<<" "<<one<<std::endl;
}