5 ms·
> If the error message of one is not very illuminating I often try the other compiler on the same piece of code. It is a good practice anyway and I should be do
by qb45 10y ago
> If the error message of one is not very illuminating I often try the other compiler on the same piece of code. It is a good practice anyway and I should be doing more of that.
It actually is a good idea to regularly build and test C/C++ codebases with both gcc and clang because not only error diagnostics are different but also warnings and optimizations, including crazy optimizations exploiting undefined behavior.
I discovered several bugs simply by compiling some code with different compilers and running the test suite each time.
- joatmon-snoo 10y agoMy first experience with UB: foo(bar(), bar()); (where bar() was stateful) Discovering that g++ and clang++ compiled to one that did what I wanted and one that didn't was an interesting experience.
- qb45 10y agoIt gets even funnier in OCaml where they nominally defined it UB in order to get the freedom to make the only existing implementation always 100% reliably evaluate right-to-left, which reportedly was better for performance or something :) And before somebody wonders about currying and eager evaluation, the problem is not functions but type constructors, which aren't curried.
- ufo 10y agoThe ocaml one is very annoying because the bytecode interpreter reliably evaluates arguments left-to-right but when you compile to native code it reliably evaluates right-to-left (or the other way around, I don't remember).
- deleted 10y ago[deleted]
- afrisch 10y agoI don't think so. Both bytecode and native evaluate right-to-left.
- ufo 10y agoI swear that I remember having programs that could behave differently in the bytecode and native compiler. Perhaps I'm remembering an older version of the compiler or another order-of-evaluation issue other than function parameters?
- gravypod 10y agoThe functions arguments are pushed onto the stack. From within the function you can think of the stack as an array. void test(a, b, c) stack[0] == a stack[1] == b stack[2] == c But to get the items in the stack in that order you have to... puch c push b push a If you wanted to do that, and still allow for left to right evaluation you could... temp_a = a temp_b = b temp_c = c push c puch b push a That would be 2x instructions for every (already expensive at that time) function call. Defining unordered evaluation as UB was to avoid having to do temp_a, temp_b, temp_c. Now compiles can do that and trivially optimize that sort of thing out.
- jacquesm 10y agoExcept that in most cases that's not how it is done. Instead, the stackframe is created in one go with a single change to the stack pointer and then the values are filled in in whatever order the compiler / language desires. Here is a typical example using GCC: movq %rsp, %rbp subq $16, %rsp movl $12, -4(%rbp) addl $1, -4(%rbp) movl -4(%rbp), %eax movl $14, %edx movl %eax, %esi movl $12, %edi call f Which moves the parameters using registers (subject to availability) as a further optimization. The 'subq' reserves space for the stackframe with addresses relative to rbp being the parameters.
- ot 10y agoThat's not UB. Argument evaluation order is unspecified, not undefined.
- wyldfire 10y agoHe meant unspecified behavior. ;)
- greglindahl 10y agoThe SGI compiler (now Open64) evaluates function arguments from right to left, unlike most other compilers. As a result we (PathScale) had to educate numerous users that the order is not guaranteed.
- kirab 10y agoStarting with C++17 evaluation order in this case (and most other cases) is finally specified and standardized! This is the accepted proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p014...
- gumby 10y agoYes! We have written a new package and compiling with the G++-6 -Wall -Werror .... and clang-++-4 -Weverything -Werror finds different bugs and different diagnostics. Although I have a long gcc bias I do use clang first as it is still faster to compile. Gcc still generates faster code for our codebase (and more importantly: faster where it matters to us) but they are pretty close and if I really had to decide between one and the other it would hardly matter. G++-7-not-quite-released appears to have better C++17 support. We may be the only people who care yet :-)
- flamedoge 10y agoI'm a little mixed about having to run both compilers for more comprehensive result. DRY principle in me tells me that devs could have concentrated effort in one compiler to make it even better.