This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can I make GCC warn on passing too-wide types to functions?
Consider the following test program:
static void func(int a)
{
}
int main()
{
unsigned int b = 42;
func(b);
return 0;
}
Compiling it with gcc:
lol#mac:~/projects$ gcc -Wconversion testit.c
testit.c: In function âmainâ:
testit.c:11: warning: passing argument 1 of âfuncâ as signed due to prototype
lol#mac:~/projects$
But, in g++ there is no warning!:
lol#mac:~/projects$ g++ -Wconversion testit.c
lol#mac:~/projects$
What is the reason for this and is there any way to get the same warning when compiling C++ code?
From the documentation for -Wconversion:
Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.
Seems that you'll need a sufficiently new version of GCC, too. I have version 4.0.1, and it doesn't recognize -Wsign-conversion.
Related
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?
My problem seems somewhat similar to Conversion from null-integer to pointer in comma list
Here is a minimal example
#include <utility>
struct Object {
double foo;
};
std::pair<Object*,int> test_function() {
typedef std::pair<Object*,int> pair_t;
return pair_t(NULL, 2);
}
// test.cc
With gcc 4.4.7, g++ -std=c++0x -c test.cc -o test.o fails with
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_pair.h:90: error: invalid conversion from \u2018long int\u2019 to \u2018Object*
It does compile if I omit -std=c++0x. Also, if I use newer versions of gcc, the compilation is fine. Is there anything wrong with the code? Should one expect such differences in gcc versions?
A later edit: I can also return pair_t((Object*)NULL, 2)
I believe the answer to your question is here:
C++ can't initialize a pointer in a pair to NULL
The NULL is represented as a long by gcc and it cannot be converted to type Object* without the explicit cast.
This question already has an answer here:
is_lock_free not defined in std::atomic<T> in gcc 4.7.2?
(1 answer)
Closed 8 years ago.
The following code fails to link:
#include <atomic>
struct A
{
unsigned long a;
unsigned long b;
};
struct B
{
void set(A tmp)
{
_a.store(tmp);
}
std::atomic<A> _a;
};
int main()
{
B b;
b.set(A());
return 0;
}
With the following error:
/tmp/cc8gyaZM.o: In function `std::atomic<A>::store(A, std::memory_order)':
dryn.cpp: (.text._ZNSt6atomicI1AE5storeES0_St12memory_order[_ZNSt6atomicI1AE5storeES0_St12memory_order]+0x3e): undefined reference to `__atomic_store_16'
If I replace the unsigned long-s with anything that is up-to int in size, this compiles just fine. Using g++ 4.7.2 . Do you have any idea why is that?
Compiled with command:
g++ dryn.cpp --std=c++11
As answered by Zeta:
Atomic API isn't complete in GCC 4.7:
When lock free instructions are not available (either through hardware or OS support) atomic operations are left as function calls
to be resolved by a library. Due to time constraints and an API
which is not finalized, there is no libatomic supplied with GCC 4.7.
This is easily determined by encountering unsatisfied external symbols
beginning with __atomic_*.
Since there is no libatomic shipped with GCC 4.7 you need to use
another compiler which actually supports the features you want or
provide the missing features (sample implementation).
This question already has answers here:
What is the strict aliasing rule?
(11 answers)
Closed 9 years ago.
In file included from /usr/local/Qt/linux-g++/include/QtCore/QLinkedList:2,
from /home/bamboo/Packages/Parser.h:17,
from /home/bamboo/Packages/Module.cpp:6:
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h: In member function 'void QLinkedList<T>::clear() [with T = int]':
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:294: error: dereferencing pointer 'y' does break strict-aliasing rules
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:293: note: initialized from here
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:294: error: dereferencing pointer 'y' does break strict-aliasing rules
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:293: note: initialized from here
where in big lines class Module contains a member template like: Parser<int> and the class parser is defined:
template <typename T> class Parser
{
// some stuff
QLinkedList<T> stuff;
};
and this piece of code compiles nicely with gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3 and nicely with g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 and fails with g++ (Debian 4.4.5-8) 4.4.5 ... and I have no idea why? Anyone has seen this error message and anyone know what this might mean?... and more importantly how to solve it?
Aliasing means that a pointer int *i points to the same address as double *d.
So if
int i = 5;
int *pi = &i:
double *d = pi;
here d is aliasing pi.
this is in c99 >illegal<
I don't know how exactly c++ treats it, but I can't imagine it is welcome.
If you want to test a code where it will be getting funny, try this code in different optimisation levels.
You will get differen results with gcc 4.2
uint32_t anint;
int main(int arg, char** argv)
{
foo ((uint64_t *)&anint);
return 0;
}
void foo (uint64_t *dblptr)
{
anint = 88;
*dblptr = 86;
dosmthng (anint);
}
void dosmthng (uint32_t val)
{
printf ("%d\r\n", val);
}
if you do -O2 or higher the output will be 88. because the compiler expects you to respect the strict-aliasing rule and expects *dblptr as never been used in this code, and jsut takes the line out.
If you any way see no way of working wihtout aliasing, you can give the compiler the param -fno-strict-aliasing. This forces GCC to do not any optimisation based on this expection.
But anyway in C it is not strict ISO C code if you do wrong type punning.
(So if it may ease you, a lot of C code on famous programms gets compiled with -fno-strict-aliasing)
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Is this a legitimate C++ code?
“C subset of C++” -> Where not ? examples ?
Could anybody come up with a piece of code that compiles with gcc or any other C compiler, and doesn't compile g++ or any other C++ compiler?
UPDATE:
I don't mean just keywords
UPDATE2:
Thank you All for answers. Apparently moderators were less enthusiastic than I was about subtle differences between C and C++.
UPDATE3:
to moderators: could you merge it with my previous question on the topic, as you suggested? It makes perfect sense to keep these two question together.
#include <stdlib.h>
int main()
{
char* s = malloc(128);
return 0;
}
This will compile with gcc, but not with g++. C++ requires an explicit cast from void* here, whereas C does not.
int main(int argc, char **class)
{
return !argc;
}
Edit: another example
int foo();
int main(void) {
return foo(42);
}
int foo(int bar) {
return bar - 42;
}
Try
extern int getSize();
int main()
{
char x[getSize()];
x[0] = 0;
}
int getSize()
{
return 4;
}
Remember to compile with the strict flags.
> gcc -pedantic -std=c99 t.c
> g++ -pedantic t.c
t.c: In function `int main()':
t.c:6: error: ISO C++ forbids variable length array `x'
How about
/* Within a function */
{
enum {foo} bar;
bar++;
}
That seems a pretty big breaking change in the design of C++, but it is what it is.
What about character size:
Even worse is that it compiles but produces different output at runtime.
#include <stdio.h>
int main()
{
fprintf(stdout, "%s\n", (sizeof('\xFF') == sizeof(char))?"OK":"Fail");
}
> gcc -pedantic t.c
> ./a.exe
Fail
> g++ -pedantic t.c
> ./a.exe
OK
This actually makes we wonder why this works?
fprintf(stdout, "%c%c\n", 'A', 'B');
It works on both compilers even though the size of the objects are different.
pointer arithmetics on void*:
void* t;
t++; // compiles only in gcc