Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
4 Added gcc version number and tested with larger -ftemplate-depth-10000 value
source | link

Produces the following error output in GCC (4.4.5):

$ g++ golf.cpp 2>&1 | wc -c
537854
$ clang golf.cpp 2>&1 | wc -c
22666
$ g++ -ftemplate-depth-500010000 golf.cpp 2>&1 | wc -c # uses268+ 266MBMB of RAM and almost 15 minutes
50375355200750356

Produces the following output in GCC:

$ g++ golf.cpp 2>&1 | wc -c
537854
$ clang golf.cpp 2>&1 | wc -c
22666
$ g++ -ftemplate-depth-5000 golf.cpp 2>&1 | wc -c # uses 266MB of RAM
50375355

Produces the following error output in GCC (4.4.5):

$ g++ golf.cpp 2>&1 | wc -c
537854
$ clang golf.cpp 2>&1 | wc -c
22666
$ g++ -ftemplate-depth-10000 golf.cpp 2>&1 | wc -c # 268+ MB of RAM and almost 15 minutes
200750356
3 added 89 characters in body
source | link
$ g++ golf.cpp 2>&1 | wc -c
537854
$ clang golf.cpp 2>&1 | wc -c
22666
$ g++ -ftemplate-depth-5000 golf.cpp 2>&1 | wc -c # uses 266MB of RAM
50375355
$ g++ golf.cpp 2>&1 | wc -c
537854
$ clang golf.cpp 2>&1 | wc -c
22666
$ g++ golf.cpp 2>&1 | wc -c
537854
$ clang golf.cpp 2>&1 | wc -c
22666
$ g++ -ftemplate-depth-5000 golf.cpp 2>&1 | wc -c # uses 266MB of RAM
50375355
2 added 375 characters in body; added 270 characters in body; added 25 characters in body
source | link

I discovered this while trying to see if C++ supports polymorphic recursionUngolfed (which, as you can clearly see, doesn'tproduces longer output). Here's a trivial example of polymorphic recursion in Haskell:

template<class T>
struct Wrap {
    T value;
    Wrap(T v) : value(v) {}
};

template<class T>
void func(T x)
{
    func(Wrap<T>(x));
}

int main(void)
{
    func(0);
    return 0;
}

I discovered this when I wanted to see if C++ supports polymorphic recursion (and, as you can clearly see, it doesn't). Here's a trivial example of polymorphic recursion in Haskell:

Prelude> let f :: (Show xa) => xa -> String; f x = show x ++ " " ++ f [x]
Prelude> f 0
"0 [0] [[0]] [[[0]]] [[[[0]]]] [[[[[0]]]]] [[[[[[0]]]]]] [[[[[[[0]]]]]]] [[[[[[[[0]] ...

Here, this requires Haskell to act like it instantiates Show x, Show [x], Show [[x]], Show [[[x]]], ad infinitum. Haskell does it by turning (Show x) => into an implicit parameter to the function f added by the compiler. C++, something like this:

type Show a = a -> String

showList :: Show a -> [a] -> String
showList show []     = "[]"
showList show (x:xs) = '[' : show x ++ showItems xs where
    showItems []     = "]"
    showItems (x:xs) = ',' : show x ++ showItems xs

f :: Show a -> a -> String
f show x = show x ++ " " ++ f (showList show) [x]

C++ does it by literally trying to construct such instances until the template instantiation depth is exceeded.

I discovered this while trying to see if C++ supports polymorphic recursion (which, as you can clearly see, doesn't). Here's a trivial example of polymorphic recursion in Haskell:

Prelude> let f :: (Show x) => x -> String; f x = show x ++ " " ++ f [x]
Prelude> f 0
"0 [0] [[0]] [[[0]]] [[[[0]]]] [[[[[0]]]]] [[[[[[0]]]]]] [[[[[[[0]]]]]]] [[[[[[[[0]] ...

Here, this requires Haskell to act like it instantiates Show x, Show [x], Show [[x]], Show [[[x]]], ad infinitum. Haskell does it by turning (Show x) => into an implicit parameter to the function f added by the compiler. C++ does it by literally trying to construct such instances until the template instantiation depth is exceeded.

Ungolfed (produces longer output):

template<class T>
struct Wrap {
    T value;
    Wrap(T v) : value(v) {}
};

template<class T>
void func(T x)
{
    func(Wrap<T>(x));
}

int main(void)
{
    func(0);
    return 0;
}

I discovered this when I wanted to see if C++ supports polymorphic recursion (and, as you can clearly see, it doesn't). Here's a trivial example of polymorphic recursion in Haskell:

Prelude> let f :: (Show a) => a -> String; f x = show x ++ " " ++ f [x]
Prelude> f 0
"0 [0] [[0]] [[[0]]] [[[[0]]]] [[[[[0]]]]] [[[[[[0]]]]]] [[[[[[[0]]]]]]] [[[[[[[[0]] ...

Here, this requires Haskell to act like it instantiates Show x, Show [x], Show [[x]], Show [[[x]]], ad infinitum. Haskell does it by turning (Show x) => into an implicit parameter to the function f added by the compiler, something like this:

type Show a = a -> String

showList :: Show a -> [a] -> String
showList show []     = "[]"
showList show (x:xs) = '[' : show x ++ showItems xs where
    showItems []     = "]"
    showItems (x:xs) = ',' : show x ++ showItems xs

f :: Show a -> a -> String
f show x = show x ++ " " ++ f (showList show) [x]

C++ does it by literally trying to construct such instances until the template instantiation depth is exceeded.

1
source | link