warning: taking address of temporary - c++

i have the following code snippet
if((compare( & key,& ALL))
All is #defined as
#define ALL (some_structure){"ALL", 3}
in g++ version
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)
compiled without any warnings
but in g++ version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4)
it is showing warning: taking address of temporary
even though it is a warning.the whole compile message shows aroung 3 million plus messages.It is a legacy code.is there any way to suppress this warning?
Edit :
Below is the sample code
#include <iostream>
using namespace std;
typedef struct test { char * name; int id; }tsTest;
void print(tsTest * T) {
cout<<endl<<"Name :"<<T->name<<endl<<"ID :"<<T->id<<endl; }
int main()
{
print(&(tsTest){"nagaraj",7});
return 0;
}
compiled fine in g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)
But in g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4)
temadd.cpp: In function ‘int main()’:
temadd.cpp:18: warning: deprecated conversion from string constant to ‘char*’
temadd.cpp:18: warning: taking address of temporary

As a workaround, you can implement operator& of the structure. Then you would not take address of the temporary, that is undefined behaviour (UB), but calling function of temporary object, returning pointer to itself.
As temporary will live as long as function call, you will not encounter any UB unless you store the pointer and dereference it after leaving the function
For your example it would be like:
typedef struct test {
const char * name;
int id;
test* operator&() {
return this;
}
}tsTest;

It's not a warning you should suppress. The problem with taking the address of a temporary is that when that temporary goes out of scope your application then exhibits undefined behaviour.
Do you have any reason for not defining ALL as a const global? You could safely take its address at any time without any UB:
struct allstruct
{
char *allname;
int somenumber;
};
const allstruct ALL { "ALL", 3 };

Related

How to get the compiler to warn that this is an invalid bool?

We just got burnt by a typo: "constexpr bool maxDistance=10000;"
Both gcc and clang compile this with no warning.
The real error here is that the variable shouldn't have been of type bool, but should have been an integer type instead.
How can we ensure we get a compiler warning in future?
#include <iostream>
constexpr bool number = 1234;
int main(int argc, char* argv[])
{
std::cout << number + 10000 << std::endl; // prints 10001.
return number;
}
The error here is that the variable is declared with the wrong type, however neither clang nor gcc give a warning.
gcc -Wall -std=c++14 test.cpp -lstdc++
clang -Wall -std=c++14 test.cpp -lstdc++
(using gcc 5.4.0 and clang 3.8.0)
Note: I've since learnt about a possible compile flag: -Wint-in-bool-context however this doesn't appear to be implemented in the version I'm using (5.4.0) nor in clang (3.8.0).
Is this the right way to go?
You should use direct list initialization syntax, it prohibits narrowing:
constexpr bool number{1234}; // error: narrowing conversion of '1234' from 'int' to 'bool' [-Wnarrowing]
I've discovered that gcc has a flag '-Wint-in-bool-context' however this doesn't appear to be implemented in the version I'm using (5.4.0) nor in clang (3.8.0).
Is this the right way to go?

C++ Ternary operator with scope resolution and condition

Following code is not being compiled by an specific compiler.
#include <iostream>
using namespace std;
class A{
public:
static const int x = 12;
static const int y = 16;
};
int main(){
int a = 12, b = 19;
int z = (a==b)?(A::x):(A::y);
cout<<z<<endl;
return 0;
}
Compiler g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) compiled it successfully.
Compiler g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17) is causing compilation error
test.cpp:(.text+0x20): undefined reference to `A::x'
test.cpp:(.text+0x28): undefined reference to `A::y'
If I replace condition (a==b) in line int z = (a==b)?(A::x):(A::y); by true or false, then it gets compiled successfully.
What is the reason and how to fix it for specified compiler?
Looks like a weak/buggy C++0x symbol-linkage implementation of gcc 4.4.
Seems that gcc 4.4 tells the linker that there are symbols but it forgot to "implement" them in one of the compilation units.
I guess if you put the initialization of the static members A::x and A::y explicitly into one unique compilation unit (e.g. corresponding .cpp file) then your code may be compatible with both compilers.

Why constexpr implicit conversion doesn't always work?

#include <iostream>
struct Index {
constexpr operator int() const { return 666; }
};
template <int i> void foo() {
std::cout << i << std::endl;
}
void wrapper(Index index) {
foo<index>();
}
int main() {
Index index;
// foo<index>(); // error: the value of ‘index’ is not usable in a constant expression
wrapper(index);
}
Hello, everyone.
I'm using a constexpr conversion of a variable "index" to an int value, which is substituted to a "foo" templated function.
If I directly call foo<index>() from "main", I get a compiler error.
If the same call is done from the "wrapper", then everything compiles and works fine.
What am I missing there?
Compile command: g++ -std=c++14 main.tex with g++ (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6).
A very similar error was reported here. It was first reported with GCC 4.9.0
In the analysis provided:
This is a GCC bug. It appears to be some sort of confusion in the way GCC handles internal linkage non-type template parameters of pointer type.
It has since been resolved.

G++ -Wshadow doesn't warn about static member shadowing

Once again I lost some hours because of mere stupidity which could have been recognized by the compiler. This is the source code in question:
class f {
static int mVar;
int g(int x) { int mVar=3; return x+mVar; }
};
int f::mVar = 1;
The problem is, that I accidentally added int in front of mVar. When I compile this with: g++ -c -Wall -Wextra -Wshadow shadowtest.cpp I don't get any warning, about the local mVar shadowing the static member mVar.
But if I don't declare the member variable to be static, then g++ correctly issues a warning:
class f {
int mVar;
f(int rVar) : mVar(rVar) {};
int g(int x) { int mVar=3; return x+mVar; }
};
compile with g++ -c -Wall -Wextra -Wshadow shadowtest2.cpp gets:
shadowtest2.cpp:5:24: warning: declaration of ‘mVar’ shadows a member of ‘f’ [-Wshadow]
int g(int x) { int mVar=3; return x+mVar; }
^
shadowtest2.cpp:3:9: note: shadowed declaration is here
int mVar;
^
Tested with g++ 4.9.2 and 5.2.1.
Is this correct behavior or a bug? Why?
Edit: I filed a bug report here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68374
Edit 2018-02-12: Doesn't warn in these versions:
g++-4.9 (Debian 4.9.4-2) 4.9.4
g++-5 (Debian 5.4.1-4) 5.4.1 20161202
g++-5 (Debian 5.5.0-8) 5.5.0 20171010
g++-6 (Debian 6.3.0-18) 6.3.0 20170516
g++-6 (Debian 6.4.0-12) 6.4.0 20180123
g++-7 (Debian 7.2.0-16) 7.2.0
g++-7 (Debian 7.3.0-3) 7.3.0
but successfully warns in:
g++-8 (Debian 8-20180207-2) 8.0.1 20180207 (experimental) [trunk revision 257435]
This looks potentially like a bug given the description of -Wshadow in the gcc documentation:
Warn whenever a local variable or type declaration shadows another variable, parameter, type, class member (in C++), or instance variable (in Objective-C) or whenever a built-in function is shadowed. Note that in C++, the compiler warns if a local variable shadows an explicit typedef, but not if it shadows a struct/class/enum.
Especially considering that clang warns for this case. This is basically a quality of implementation issue since this is not ill-formed code. I would file a bug report. Most likely they they will provide a rationale for not warning in this case or they will eventually fix the warnings.
It looks like gcc used to warn about this case if we go all the way back to version 4.5.4 see it live.

C++ constructor/copy constructor issues in g++ 3.4.6

Here is a code snippet:
class test {
public:
test(){
cout<<"I am in default constructor ";
}
static void func(const test &obj){
cout<<"I am in function ";
}
protected:
test( const test &o){
cout<<"I am in copy constructor ";
}
};
int main()
{
test::func(test());
}
The above code gives following error with g++ 3.4.6 (on Red Hat Linux) on compilation:
In function `int main()':
error: `test::test(const test&)' is protected
error: within this context
However if you compile with g++ 3.3.2 or g++ 4.4.3 or any other g++ version (on Red Hat Linux), it compiles successfully and gives following output:
I am in default constructor I am in function
In the above code, I have passed the temporary object (created by default constructor) to function func by reference. So why the compiler 3.4.6 is calling the copy constructor?
Most likely because older g++ versions (and I believe it stands for other compilers) were not fully c++ compliant and had more bugs then the current version. As you said, this works on a later version, therefore it is most likely fixed.
EDIT
by the way, have you tried changing compiler settings? Different optimization levels might have different bugs.