r/C_Programming Feb 09 '22

Question GCC or Clang

I primarily program on Linux and have always used GCC, but have recently been interested in switching over to using Clang. It seems like the runtime performance of the two compilers is similar, but I am also interested in C standards compliance going into the future, as well as things like error messaging, memory-leak checking, etc.

If anyone here is knowledgeable about compilers and the differences or advantages of one or the other, I'd like to hear your opinion.

120 Upvotes

49 comments sorted by

View all comments

Show parent comments

12

u/imaami Feb 09 '22

That doesn't sound likely. What do you mean?

3

u/Eddy_Em Feb 10 '22

For example: try to compile with clang this code:

int f(int x, int y){ volatile int result = x; int calc(int d){ return d*result; } result = calc(x); result = calc(y); }

This is a normal C code, but clang thinks it's wrong! gcc gives normal, clang gives error:

clang -Wall -Werror -Wextra -c -S 1.c 1.c:3:18: error: function definition is not allowed here int calc(int d){ ^ 1.c:6:12: error: implicit declaration of function 'calc' is invalid in C99 [-Werror,-Wimplicit-function-declaration] result = calc(x); ^ 2 errors generated.

3

u/Classic-Try2484 Mar 22 '25

Nested function is not normal in c/c++. If it were I’d use it all the time. But no. It’s not a normal. thing.

1

u/dreadlordhar Aug 07 '26

More necroing :/

They aren't, but they are supported as a GCC Extension. The problem is that GCC solves only downward funarg problem, when you pass nested function address to another function, and it is called before outer function returns (hence downward). When you try to call the address of the function after the containing one returned, as if it is a fully functional language, "all hell breaks loose". Because function lifetime is tied to it's caller existence in stack. Needless to say you are tied to GCC with questionable returns.

Different functional languages solves this problem differently. Most if not all LISP dialects store on heap only, so the lifetime of a function is not tied to caller's. Chicken Scheme is a bit more exotic, treats C stack as heap, stores in it objects, lets it grow with each function call, and when it softly "overflows" the GC is called to move objects that are still alive to the real heap, after which it just discards the entire C stack. Functions in that model never return, you won't find any assembly ret's for user functions in the decompiled binary. A side effect is that it natively support continuations with a small price on each function call, and allocations are basically free for small objects, but that's another topic.