Piece of code that compiles with gcc but not g++ [duplicate] - c++

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

Related

c++ variable size stack array in function that get const

I'm learning now C++ I'm reading the book Effective C++ (Scott Meyers).
In the book, there is an item about const variables, and I try to work with them.
I notice something very interesting that I what to know if it bug in C++:
(I'm working with C++98 standard)
void Test(const int i)
{
int arr[i] = {0};
for (int j = 0; i > j; ++j)
{
arr[j] = i;
}
}
This function will compile and work exactly as I want (create int array on the stack with the size of 'i'. When I remove the 'const' from 'i' it won't compile.
I try this on gcc and clang.
Edit:
link to Compiler Explorer
To catch this kind of mistake in the future the compiler flag you want for both g++ and clang++ is -pedantic. And always remember to specify your language standard or you don't know what you'll get.
$ g++ -std=c++98 -pedantic c++-vla.cpp -o c++-vla
c++-vla.cpp: In function ‘void f(size_t)’:
c++-vla.cpp:3:30: warning: ISO C++ forbids variable length array ‘g’ [-Wvla]
3 | void f(const size_t x) { int g[x]; }
| ^
$ clang++ -std=c++98 -pedantic c++-vla.cpp -o c++-vla
c++-vla.cpp:3:31: warning: variable length arrays are a C99 feature [-Wvla-extension]
void f(const size_t x) { int g[x]; }
^
1 warning generated.
First of all, const in your function signature is ignored by the compiler. So the following two are equivalent:
Test(const int i) {}
Test(int i) {}
Secondly, this isn't valid C++ regardless of whether it compiles or not:
int arr[i] = {0};
It isn't valid because i is not a compile time constant i.e., the value of i has to be known at the time of compilation.
Try on Compiler Explorer

Why am I able to assign a function reference to an anonymous function pointer variable?

The following code compiles just fine and I'm not sure why. Can someone please explain to me why this is legal?
I am using g++ (Debian 6.1.1-10) 6.1.1 20160724 to compile.
#include <iostream>
int sum(int x, int y) { return x + y; }
int main(int argc, char *argv[])
{
using std::cout;
int (*) (int, int) = ∑
cout << "what" << '\n';
}
Addendum
The following program compiles fine using g++ version 5.4.0 but fails to compile in gcc.
int main()
{
int (*) = 20;
}
It's very likely to be related to this bug reported by Zack Weinberg:
Bug 68265 - Arbitrary syntactic nonsense silently accepted after 'int (*){}' until the next close brace
(From Why does this invalid-looking code compile successfully on g++ 6.0? :)
The C++ compiler fails to diagnose ill-formed constructs such as
int main()
{
int (*) {}
any amount of syntactic nonsense
on multiple lines, with *punctuation* and ++operators++ even...
will be silently discarded
until the next close brace
}
With -pedantic -std=c++98 you do get "warning: extended initializer
lists only available with -std=c++11 or -std=gnu++11", but with
-std=c++11, not a peep.
If any one (or more) of the tokens 'int ( * ) { }' are removed, you do
get an error. Also, the C compiler does not have the same bug.
Of course, if you try int (*) (int, int) {} or other variants, it erroneously compiles. The interesting thing is that the difference between this and the previous duplicate/bug reports is that int (*) (int, int) = asdf requires asdf to be a name in scope. But I highly doubt that the bugs are different in nature, since the core issue is that GCC is allowing you to omit a declarator-id.
[n4567 §7/8]: "Each init-declarator in the init-declarator-list
contains exactly one declarator-id, which is the name declared by
that init-declarator and hence one of the names declared by the
declaration."
Here's an oddity:
int (*) (int, int) = main;
In this specific scenario, GCC doesn't complain about taking the address of main (like arrays, &main is equivalent to main).

c++ strict-aliasing rules compile error with Qt and QLinkedList [duplicate]

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)

g++ special handling of printf

Anyone knows why the following code works under g++ 4.7.2? If I change the name printf to another name such as f, it has compiler error saying constexpr can't contain non-const function calls (which I think is the correct behavior).
[hidden]$ cat d.cpp
extern "C" { extern int printf(const char* s, ...); }
constexpr int g() { return printf(""), 0; }
template <int N> struct X { const static int value = N; };
int n = X<g()>::value;
[hidden]$ g++ -std=c++11 -c d.cpp
[hidden]$ g++ -v |& tail -1
gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC)
Note I don't include any header files.
printf() is handled as a builtin function by GCC/g++ in many cases (though I think this behavior is still a bug). From http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html:
The ISO C90 functions ... printf ... are all recognized as built-in functions unless -fno-builtin is specified (or -fno-builtin-function is specified for an individual function)
You get the correct diagnostic if you use the -fno-builtin option.
The bug appears to be fixed in 4.8.0.
I think stdio.h is included by default
I try it with puts and works for me [gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)]
extern "C" { extern int puts(const char* s); }
constexpr int g() { return puts(""), 0; }
template <int N> struct X { const static int value = N; };
int n = X<g()>::value;
Edit:
#Keith Thompson
Before I wrote "included by default" I tried the code below without #include <stdio.h>. It compiles with some warnings but runs - so (for some reason) printf, scanf, puts works without #include <stdio.h>. Maybe stdio.h is not included by default, maybe library with printf, scanf, puts is linked by default.
int main()
{
char one;
printf("Hello ");
scanf("%c", &one);
puts("world!");
}

Difference between -Wconversion between gcc and g++ [duplicate]

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.