How to drive C#, C++ or Java compiler to compute 1+2+3+...+1000 at compile time?

Solution 1:

Updated Now with improved recursion depth! Works on MSVC10 and GCC without increased depth. :)


Simple compile-time recursion + addition:

template<unsigned Cur, unsigned Goal>
struct adder{
  static unsigned const sub_goal = (Cur + Goal) / 2;
  static unsigned const tmp = adder<Cur, sub_goal>::value;
  static unsigned const value = tmp + adder<sub_goal+1, Goal>::value;
};

template<unsigned Goal>
struct adder<Goal, Goal>{
  static unsigned const value = Goal;
};

Testcode:

template<unsigned Start>
struct sum_from{
  template<unsigned Goal>
  struct to{
    template<unsigned N>
    struct equals;

    typedef equals<adder<Start, Goal>::value> result;
  };
};

int main(){
  sum_from<1>::to<1000>::result();
}

Output for GCC:

error: declaration of ‘struct sum_from<1u>::to<1000u>::equals<500500u>’

Live example on Ideone.

Output for MSVC10:

error C2514: 'sum_from<Start>::to<Goal>::equals<Result>' : class has no constructors
      with
      [
          Start=1,
          Goal=1000,
          Result=500500
      ]

Solution 2:

C# example to error at compile time.

class Foo
{
    const char Sum = (1000 + 1) * 1000 / 2;
}

Produces the following compilation error:

Constant value '500500' cannot be converted to a 'char' 

Solution 3:

I should just write a program that could drive the compiler to compute this sum while compilation and print the result when compilation completes.

A popular trick to print a number during compilation is trying to access a non-existent member of a template instantiated with the number you want to print:

template<int> struct print_n {};

print_n<1000 * 1001 / 2>::foobar go;

The compiler then says:

error: 'foobar' in 'struct print_n<500500>' does not name a type

For a more interesting example of this technique, see Solve the eight queens problem at compile-time.

Solution 4:

Since neither compiler nor language were specified in the interview question, I dare submit a solution in Haskell using GHC:

{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -ddump-splices #-}
module Main where

main :: IO ()
main = print $(let x = sum [1 :: Int .. 1000] in [| x |])

Compile it:

$ ghc compsum.hs
[1 of 1] Compiling Main             ( compsum.hs, compsum.o )
Loading package ghc-prim ... linking ... done.
<snip more "Loading package ..." messages>
Loading package template-haskell ... linking ... done.
compsum.hs:6:16-56: Splicing expression
    let x = sum [1 :: Int .. 1000] in [| x |] ======> 500500
Linking compsum ...

And we got a working programme also.