C++ Ternary operator with scope resolution and condition - c++

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.

Related

GCC and Clang differ in static_assert related to __builtin_constant_p

I happen to find that GCC and Clang differ in the compilation of the following code:
struct Foo
{
int mem = 42;
};
int main()
{
constexpr Foo foo;
static_assert(__builtin_constant_p(foo));
return 0;
}
I compile with g++ -std=c++17 and clang++ -std=c++17.
In particular,
g++ g++-9 (Homebrew GCC 9.3.0_1) 9.3.0 compiles, whereas
clang++ Apple clang version 11.0.3 (clang-1103.0.32.62) fails to compile, complaining that
error: static_assert failed due to requirement '__builtin_constant_p(foo)'
static_assert(__builtin_constant_p(foo));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
I didn't find any hint that there should be any difference regarding __builtin_constant_p.
For __builtin_constant_p
GCC says
You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile time ...
Clang
says
Clang supports a number of builtin library functions with the same syntax as GCC, including things like __builtin_nan, __builtin_constant_p, __builtin_choose_expr, __builtin_types_compatible_p, __builtin_assume_aligned, __sync_fetch_and_add, etc.
Question: While I know __builtin_constant_p is a compiler extension, which one should be the correct one?
Both are poorly documented so I doubt there is a proper answer to your question.
If you need a workaround: it seems that clang gives up if the argument is not an int.
So this works:
struct Foo
{
int mem = 42;
};
int main()
{
constexpr Foo foo;
static_assert(__builtin_constant_p(foo.mem));
return 0;
}

warning: taking address of temporary

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 };

unused-variable warning different for auto variables

Using gcc (4.7.2 here) I get warnings about unused auto variables, but not about other variables:
// cvars.h
#ifndef CVARS_H_
#define CVARS_H_
const auto const_auto = "const_auto";
const char const_char_array[] = "const_char_array";
const char * const_char_star = "const_char_star";
const char use_me = 'u';
#endif // CVARS_H_
//---
//comp_unit.cpp
#include "cvars.h"
void somef()
{
//const_auto // commented out - unused
use_me; // not using any of the others either
}
// compile with $ g++ -std=c++11 -Wunused-variable -c comp_unit.cpp
// gcc outputs warning: ‘cvars::const_auto’ defined but not used [-Wunused-variable]
// but does not complain about the other variables
Is this an inconsistency in GCC?
1.1 If so, what should happen in all cases, warning or no warning?
1.2 If not, what is the reason for the difference in behavior?
Note: Concerning 1.1, I imagine no warning should be printed in this case (this is what clang does). Otherwise, any compilation unit including a constant-defining header but not using all the constants within would contain lots of warnings.
These warnings are entirely up to the implementation, so there is no "should". But, yes, I agree: constants would ideally not generate these warnings even when declared using auto.
Since I can reproduce your observation in GCC 4.7 and GCC 4.8.0, but not in GCC 4.8.1 or 4.9, I'd say the guys over at GNU would agree too. In fact, I believe you're seeing bug 57183.

std::function<> and the Intel compiler version 11.1

I'm having trouble working with lambda functions in the Intel compiler, in particular, the following code won't compile:
template<typename T>
std::function<T (int)> make_func(T x) {
return [=](int index) -> T
{
return x;
};
}
The error I get is
error: namespace "std" has no member "function"
The code compiles and runs fine on my Mac, (macports gcc version 4.5). The error is at work, where we use the Intel compiler version 11.1. It does accept lambda functions (with the -std=c++0x option), such as:
auto lam = [=](int j) -> int {
printf("testing for lambdas: %d\t%d\n", n, j);
return n;
};
int g = lam(7);
The version of gcc installed at work is 4.1.2, so I'm guessing that the standard library is old?
/bin/libc.so.6
says it's version 2.5 compiled with gcc 4.1.2.
Is there a way around this?
thanks in advance for any help
I get the same behavior with icc 11.1 on a system where gcc 4.5.2 is installed.
g++'s header <functional> is protected with #ifdef __GXX_EXPERIMENTAL_CXX0X__ which is not defined when icc is used.
I would consider switching to boost::function in this setup, which of course works with icc.
Well, the code shown doesn't include a single header. And yet you refer to the standard library std::function.
So no, it doesn't compile. As with any other part of the standard library, you need to include the header where std::function is defined: <functional>.

Compiling with operator() under GCC 3.3 Problem in Boost

I have the following snippet:
#include <boost/random/lognormal_distribution.hpp>
#include <boost/random/lagged_fibonacci.hpp>
int main() {
const double mean = 0.0;
const double sigma = 1.0;
boost::lognormal_distribution<double> lognorm_dist(mean, sigma);
boost::lagged_fibonacci44497 engine;
// the following line give error in GCC 3.3
const double value = lognorm_dist.operator() <boost::lagged_fibonacci44497>((engine));
}
It compile fine under
i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5465)
But under:
g++ (GCC) 3.3.3 (SuSE Linux)
It gave the following error:
Mycode.cc:10:error: `operator()' not defined
How can I fix the problem?
Why not just lognorm_dist( engine );? Providing "function-like" syntax is the whole point of operator(). That said, lognorm_dist.template operator() <boost::lagged_fibonacci44497>((engine)) should solve your compilation issues if I am not mistaken.