
C/C++ Fiddle - United857
http://gcc.godbolt.org/
======
vinkelhake
GCC Explorer is great and I use it on a semi-regular basis. I often use it to
show what kinds of optimizations a modern compiler will do. Just yesterday I
was using it to show someone how a piece of code like:

    
    
        int launched = 0;
        // ...
        start_thread(...);
        while (!launched) {}
    

could result in an endless loop since the compiler just rewrote it to
'if(!launched) { while(true){} }'. The person had the thread write to
'launched' and expected the first thread to exit the loop once launched had
been set to 1.

Great tool. I hope it doesn't get a HN hug of death.

~~~
nly
Unless 'launched' was directly or indirectly local to the stack frame, I don't
see how this optimisation is legal. In general your compiler has to assume
values will change across an opaque function call.

~~~
vinkelhake
To expand on what to3m said. The code was transformed into something like
this:

    
    
        int launched = 0;
        start_thread(...);
        if (!launched) {
          while (true) {}
        }
    

That's a perfectly legal optimization. The integer here isn't atomic and if
another thread modifies the variable, that would be a data race and those have
undefined behavior. Therefore, the compiler can assume that there is no race
and move the comparison out of the loop.

Changing it to be "std::atomic<int> launched;" fixes that problem.

~~~
cube13
>That's a perfectly legal optimization. The integer here isn't atomic and if
another thread modifies the variable, that would be a data race and those have
undefined behavior. Therefore, the compiler can assume that there is no race
and move the comparison out of the loop.

In this case, the data race is fairly minimal, since we're talking about a 4
byte integer being used as a boolean flag. Operations like x = 1 for 4 byte
ints are pretty much guaranteed to be atomic with x86, and worst case, you go
through 1 more iteration of your loop than you would have otherwise(which your
code should account for at any rate with locking for critical sections). Any
change to the int should cause the while loop to exit.

It should be a volatile(C pre C11) or atomic(C++11/C11) integer if you're
passing it between threads, though.

------
mattgodbolt
Hi! I'm the developer of GCC Explorer and ... sorry for the slow service! This
is the second time I've made it on HN - thanks for all your support. GCC
Explorer runs on an Amazon EC2 instance and my "secondary" instance that I
spin up from time to time is woefully out of date...

~~~
mattgodbolt
Better late than never...I've increased the power and number of instances
running GCC Explorer, so hopefully it's a lot more usable under load now.
Although my HN 5-minute fame seems to be over now :)

------
dmunoz
GCC Explorer is awesome, but I would not call it a "C/C++ Fiddle".

It's really slow (unusable) at the moment due to, I reckon, being on HN. Do
revisit it later!

I have had some issues with it in the past when importing just iostream and
trying to see the output for a small example. The combined source is too
large, and GCC Explorer refuses to compile and show the assembly sometimes for
even small examples.

Do play with the settings. Colourise is especially nice.

The code is on GitHub [0], so I suppose you can self host it, although I have
not tried to do so yet.

[0] [https://github.com/mattgodbolt/gcc-
explorer](https://github.com/mattgodbolt/gcc-explorer)

~~~
azakai
> It's really slow (unusable) at the moment due to, I reckon, being on HN. Do
> revisit it later!

Unfortunate. Running this on the client side would avoid that, I wonder if
they considered that option.

~~~
epi8
Running this on the client side would require a C++ compiler in javascript,
right? I don't know much about web dev.

~~~
azakai
Yes, there are demos of such things. For example, these two:

[http://kripken.github.io/clangor/demo.html](http://kripken.github.io/clangor/demo.html)

[http://kripken.github.io/llvm.js/demo.html](http://kripken.github.io/llvm.js/demo.html)

A bit old by now, but the first compiles C++ into LLVM IR, the second LLVM IR
into JS and runs it. All of that happens clientside.

------
panzi
"fiddle"? I expected it to run the code. But for running simple C/C++ code I
made me these anyway:

[https://gist.github.com/panzi/7010082](https://gist.github.com/panzi/7010082)
[https://gist.github.com/panzi/7010082](https://gist.github.com/panzi/7010082)

C example (-i for include, -p for printf, standard flags: -I, -L, -l, -W, -O,
-D, -S, -E):

    
    
        $ cexpr -imath.h -iunistd.h -p '%f %d' 'pow(2,3)' 'getuid()'  
        8.000000 1000
    

C++ example (-i for include, standard flags: -I, -L, -l, -W, -O, -D, -S, -E):

    
    
        $ cppexpr -ilimits 'std::numeric_limits<long>::max()' '"hello world"'
        9223372036854775807 hello world

------
w_t_payne
Neat tool. Could do with a "diff" function to quickly see impact of code
changes.

~~~
mattgodbolt
Agreed! It's on the backlog of TODOs! Patches welcome, of course :)

------
ZephyrP
Seems rad, but is this any different than providing `-S` to gcc or the
equivalent option to your compiler of choice?

Also, I assume the author has thought of this, but just throwing this out
there....

`-ftemplate-depth1024` (1024 should guarantee a stack overflow)

    
    
      #include <iostream>
      template<int N>
      struct ZVTemplate{
        static void out(std::ostream& os)
        {
          ZVTemplate<N>::out(os);
          os << "zv was here" << std::endl;
        }
      };
      template<>
      struct ZVTemplate<1>{
        static void out(std::ostream& os)
        {
          os << "deftly evaded :)" << std::endl;
        }
      };
      int main(){
         ZVTemplate<2>::out(std::cout);
      }

~~~
mattgodbolt
I'm not quite sure what you were expecting to happen - here the template just
recurses, but as a run-time recursion. GCC and the explorer handle it just
fine.

Doing the more usual template<N-1> trick lets you hit the -ftemplate-depth
limit if you pass, for example ZVTemplate<2048>. It still works ok though :)

Please do let me know if you can find a "poison" input...although at the
moment the site is pretty busy just through sheer weight of users, so it's
hard to tell I know!

Thanks, Matt

------
onnoonno
Cool! As feature requests are piling up here: I would like to be able to
switch the machine/backend. Optimal would be a drop down menu to select

-x86_64 -x86 -arm -mips -or32 -avr

and so on. Yeah, I guess that requires a couple recompiled GCC binaries :D

~~~
14113
Presumably would require cross compilers for each architecture, but it would
be very interesting to see what you could do with it, for example comparing
side by side.

------
eco
Also supports D (GDC, the gcc backend to D).

[http://d.godbolt.org/](http://d.godbolt.org/)

------
marcocampos
First thing I tried: fork bomb.

~~~
adamnemecek
It does not execute your code, just compile it and disassemble it.

~~~
marcocampos
Dammit, I had to try! :)

~~~
mattgodbolt
You're not the only one!

I've had to put a variety of "anti-hacker" features into the public instance,
even though it runs on a (somewhat) throwaway EC2 instance.

Check out the source, and the LDPRELOAD stuff I do to try and make the
compilers vaguely secure...!

~~~
panzi
But did you secure it against endless parser loops? At least older g++
versions have a problem with this:

    
    
        template<class T> struct Loop { Loop<T*> operator->(); };
        Loop<int> i, j = i->hooray;
    

And on older gcc versions this eats a gig RAM and a takes couple of hours:

    
    
        struct a{typedef int foo;};struct a1:a{};struct a2:a{};
        #define X(b,a) struct a##1:b##1,b##2{};struct a##2:b##1,b##2{};
        X(a,b)X(b,c)X(c,d)X(d,e)X(e,f)X(f,g)X(g,h)X(h,i)X(i,j)X(j,k)X(k,l)
        X(l,m)X(m,n) n1::foo main(){}
    
    

From slide 11 and 12 of this presentation:
[http://www.fefe.de/c++/c%2B%2B-talk.pdf](http://www.fefe.de/c++/c%2B%2B-talk.pdf)

~~~
mattgodbolt
I've done my best to protect against these too with both babysitting process
timeouts and as a last line of defense, ulimit "limits".

Thanks for sharing those utterly evil examples though! :D

------
cmollis
this is awesome. Am I the only person who thinks C++ is going to win?

~~~
tylerlh
..win what?

