2012-01-06 13 views
120

In una recente intervista, mi è stata fatta una domanda davvero strana. L'intervistatore mi ha chiesto come posso calcolare 1 + 2 + 3 + ... + 1000 usando solo le caratteristiche del compilatore. Ciò significa che non sono autorizzato a scrivere un programma ed eseguirlo, ma dovrei semplicemente scrivere un programma che possa guidare il compilatore a calcolare questa somma durante la compilazione e stampare il risultato al termine della compilazione. Come suggerimento, mi ha detto che potrei usare le funzioni generiche e pre-processore del compilatore. È possibile utilizzare C++, C# o compilatore Java. Qualche idea???Come eseguire il compilatore C#, C++ o Java per calcolare 1 + 2 + 3 + ... + 1000?

Questa domanda non è correlata al calcolo della somma senza loop asked here. Inoltre, si dovrebbe notare che la somma DOVREBBE essere calcolata durante la compilazione. Stampare solo il risultato usando le direttive del compilatore C++ non è accettabile.


lettura più sulle risposte pubblicate, ho scoperto che la soluzione dei problemi durante la compilazione utilizzando i modelli C++ si chiama metaprogrammazione. Questa è una tecnica scoperta casualmente dal Dr. Erwin Unruh durante il processo di standardizzazione del linguaggio C++. Puoi leggere ulteriori informazioni su questo argomento allo wiki page of meta-programming. Sembra che sia possibile scrivere il programma in Java usando le annotazioni java. Puoi dare un'occhiata a maress's rispondi sotto.

Un bel libro sulla meta-programmazione in C++ è this one. Vale la pena dare un'occhiata se interessati.

Un'utile libreria di meta-programmazione C++ è la MPLdi Boost.

+17

#error "500500" Un errore di compilazione conta come "completato"? – Mysticial

+4

L'hint significa essenzialmente che tu usi i modelli C++. Ovviamente non è la stessa cosa ma questa è per la stampa da 1 a 1000, sono sicuro che puoi modificarlo per aggiungerne mille ... http://stackoverflow.com/questions/4568645/printing-1-to-1000- senza-loop-or-conditionals – Joe

+7

'const valore int = 1 + 2 + 3 .... + 1000; Console.WriteLine (valore); '; P –

risposta

114

Aggiornamento Ora con profondità di ricorsione migliorata! Funziona su MSVC10 e GCC senza aumentare la profondità. :)


semplice fase di compilazione ricorsione + aggiunta:

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(); 
} 

Uscita per GCC:

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

Live example on Ideone.

Uscita per MSVC10:

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

@hsalimi: ho modificato la risposta per mostrare effettivamente un codice che ha portato a termine il lavoro. :) – Xeo

+0

Wow, mi hai davvero colpito :-) – hsalimi

+0

@hsalimi: È stato il Dr. Erwin Unruh che ha inventato questa tecnica durante la riunione di standardizzazione del C++ del 1997 a Stoccolma. Ha calcolato una serie di numeri primi. –

2

È possibile utilizzare (e principalmente abusare) macro/modelli C++ per fare metaprogramming. AFAIK, Java non consente lo stesso tipo di cosa.

+0

+1 Grazie per il collegamento. Sembra utile. – hsalimi

+2

Non proprio una risposta alla domanda. – Ikke

+0

Penso che tu abbia ragione. In java non è possibile utilizzare lo stesso trucco di ricorsione del modello, poiché un parametro di classe generico non può essere un valore - deve essere una classe. –

1

In teoria, è possibile utilizzare questo:

#include <iostream> 

template<int N> 
struct Triangle{ 
    static int getVal() 
    { 
    return N + Triangle<N-1>::getVal(); 
    } 
}; 

template<> 
struct Triangle<1>{ 
    static int getVal() 
    { 
    return 1; 
    } 
}; 

int main(){ 
    std::cout << Triangle<1000>::getVal() << std::endl; 
    return 0; 
} 

(in base al codice che Xeo postato). Ma GCC mi dà questo errore:

triangle.c++:7: error: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating struct Triangle<500>

più un'enorme pseudo-stacktrace.

+0

Devi usare la bandiera: -ftemplate-depth-1000 – Jetti

+0

@Jetti: Beh, sì; questo è quello che dice il messaggio di errore. :-) – ruakh

+0

+1 funziona per numeri inferiori a 500, ad es. 450? – hsalimi

49

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

Un trucco popolare per stampare un numero durante la compilazione sta cercando di accedere a un membro inesistente di un modello istanziata con il numero che si desidera stampare:

template<int> struct print_n {}; 

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

Il compilatore dice poi:

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

Per un esempio più interessante di questa tecnica, vedere Solve the eight queens problem at compile-time.

+0

+1 Piuttosto intelligente, infatti, –

+0

+1 Grazie. Bel pensiero. :-) Ma non COMPUTA la somma. – hsalimi

+0

Si potrebbe anche solo lasciare che 'print_n' rimanga indefinito, vedere la mia risposta. – Xeo

88

C# esempio di errore in fase di compilazione.

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

produce il seguente errore di compilazione:

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

@ildjarn Beh, c'è una differenza tra le risposte del template C++ e questa: Questo qui funziona solo a causa della costante piegatura mentre il modello consente il codice arbitrario (?). Ancora una buona idea assegnarlo a un char! – Voo

+0

@Voo Sì, ma per essere onesti C# non si confronta con C++ per questo tipo di programmazione. – Marlon

+2

@ Marion E non considero davvero un errore nella progettazione del linguaggio;) la meta-programmazione dei template potrebbe essere molto potente, ma altri linguaggi possono ancora fare la maggior parte delle cose con altre soluzioni che non hanno tutte quelle trappole. Ho dovuto lavorare su un progetto che ha richiesto ore per essere compilato (non completamente vero - è stato incredibilmente veloce se non avessimo aumentato il limite di istanza ricorsiva .. fallito in pochi secondi) ed è stato orribile da mantenere. Probabilmente un motivo per cui non ne sono molto entusiasta .. – Voo

7

Ecco un'implementazione che lavora sotto VC++ 2010. Ho dovuto rompere i calcoli fino in 3 fasi dal momento che il compilatore lamentava quando i modelli ricorsivo 500+ volte .

template<int t_startVal, int t_baseVal = 0, int t_result = 0> 
struct SumT 
{ 
    enum { result = SumT<t_startVal - 1, t_baseVal, t_baseVal + t_result + 
     t_startVal>::result }; 
}; 

template<int t_baseVal, int t_result> 
struct SumT<0, t_baseVal, t_result> 
{ 
    enum { result = t_result }; 
}; 

template<int output_value> 
struct Dump 
{ 
    enum { value = output_value }; 
    int bad_array[0]; 
}; 

enum 
{ 
    value1 = SumT<400>::result,    // [1,400] 
    value2 = SumT<400, 400, value1>::result, // [401, 800] 
    value3 = SumT<200, 800, value2>::result // [801, 1000] 
}; 

Dump<value3> dump; 

Quando si compila questo, si dovrebbe vedere questo output del compilatore qualcosa di simile:

1>warning C4200: nonstandard extension used : zero-sized array in struct/union 
1>   Cannot generate copy-ctor or copy-assignment operator when UDT contains a 
zero-sized array 
1>   templatedrivensum.cpp(33) : see reference to class template 
instantiation 'Dump<output_value>' being compiled 
1>   with 
1>   [ 
1>    output_value=500500 
1>   ] 
+0

Un'idea molto carina con l'abbattimento, penso che lo incorporerò nella mia risposta in qualche modo. +1 :) – Xeo

+0

+1 Nizza ... grazie. – hsalimi

30

Poiché né compilatore né la lingua sono stati specificati nella questione intervista, oso presentare una soluzione in Haskell utilizzando GHC:

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

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

compilarlo:

$ 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 ... 

E abbiamo anche un programma di lavoro.

18

La vita sarà molto più semplice con C++ 11 che aggiunge le funzioni constexpr per il calcolo del tempo di compilazione, anche se sono attualmente supportate solo da gcc 4.6 o successive.

constexpr unsigned sum(unsigned start, unsigned end) { 
    return start == end ? start : 
     sum(start, (start + end)/2) + 
     sum((start + end)/2 + 1, end); 
} 

template <int> struct equals; 
equals<sum(1,1000)> x; 

La norma richiede solo il compilatore per supportare una profondità di ricorsione di 512, quindi ancora deve evitare profondità di ricorsione lineare. Ecco l'output:

$ g++-mp-4.6 --std=c++0x test.cpp -c 
test.cpp:8:25: error: aggregate 'equals<500500> x' has incomplete type and cannot be defined 

Naturalmente si può semplicemente utilizzare la formula:

constexpr unsigned sum(unsigned start, unsigned end) { 
    return (start + end) * (end - start + 1)/2; 
} 

// static_assert is a C++11 assert, which checks 
// at compile time. 
static_assert(sum(0,1000) == 500500, "Sum failed for 0 to 1000"); 
+1

+1, completamente dimenticato di 'constexpr' per un momento. Forse adoro i modelli troppo. :( – Xeo

+0

Questo è un buon uso di constexpr per rispondere alla domanda (vedi l'implementazione del Adder): http://kaizer.se/wiki/log/post/C++_constexpr_foldr/ – Matt

12

in Java, ho pensato di usare l'elaborazione di annotazione. Lo strumento apt analizza il file sorgente prima di analizzare effettivamente il file sorgente nel comando javac.

Durante la compilazione dei file di origine, l'uscita viene stampato:

@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.TYPE, ElementType.METHOD}) 
public @interface MyInterface { 

    int offset() default 0; 

    int last() default 100; 
} 

La fabbrica del processore:

public class MyInterfaceAnnotationProcessorFactory implements AnnotationProcessorFactory { 

    public Collection<String> supportedOptions() { 
     System.err.println("Called supportedOptions............................."); 
     return Collections.EMPTY_LIST; 
    } 

    public Collection<String> supportedAnnotationTypes() { 
     System.err.println("Called supportedAnnotationTypes..........................."); 
     return Collections.singletonList("practiceproject.MyInterface"); 
    } 

    public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> set, AnnotationProcessorEnvironment ape) { 
     System.err.println("Called getProcessorFor................"); 
     if (set.isEmpty()) { 
      return AnnotationProcessors.NO_OP; 
     } 
     return new MyInterfaceAnnotationProcessor(ape); 
    } 
} 

Il processore annotazione attuale:

public class MyInterfaceAnnotationProcessor implements AnnotationProcessor { 

    private AnnotationProcessorEnvironment ape; 
    private AnnotationTypeDeclaration atd; 

    public MyInterfaceAnnotationProcessor(AnnotationProcessorEnvironment ape) { 
     this.ape = ape; 
     atd = (AnnotationTypeDeclaration) ape.getTypeDeclaration("practiceproject.MyInterface"); 
    } 

    public void process() { 
     Collection<Declaration> decls = ape.getDeclarationsAnnotatedWith(atd); 
     for (Declaration dec : decls) { 
      processDeclaration(dec); 
     } 
    } 

    private void processDeclaration(Declaration d) { 
     Collection<AnnotationMirror> ams = d.getAnnotationMirrors(); 
     for (AnnotationMirror am : ams) { 
      if (am.getAnnotationType().getDeclaration().equals(atd)) { 
       Map<AnnotationTypeElementDeclaration, AnnotationValue> values = am.getElementValues(); 
       int offset = 0; 
       int last = 100; 
       for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : values.entrySet()) { 
        AnnotationTypeElementDeclaration ated = entry.getKey(); 
        AnnotationValue v = entry.getValue(); 
        String name = ated.getSimpleName(); 
        if (name.equals("offset")) { 
         offset = ((Integer) v.getValue()).intValue(); 
        } else if (name.equals("last")) { 
         last = ((Integer) v.getValue()).intValue(); 
        } 
       } 
       //find the sum 
       System.err.println("Sum: " + ((last + 1 - offset)/2) * (2 * offset + (last - offset))); 
      } 
     } 
    } 
} 

Poi siamo crea un file sorgente. semplice classe che utilizza MyInterface nota:

@MyInterface(offset = 1, last = 1000) 
public class Main { 

    @MyInterface 
    void doNothing() { 
     System.out.println("Doing nothing"); 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     // TODO code application logic here 
     Main m = new Main(); 
     m.doNothing(); 
     MyInterface my = (MyInterface) m.getClass().getAnnotation(MyInterface.class); 
     System.out.println("offset: " + my.offset()); 
     System.out.println("Last: " + my.last()); 
    } 
} 

Il processore annotazione viene compilato in un file jar, quindi lo strumento apt viene utilizzato per compilare il file sorgente come:

apt -cp "D:\Variance project\PracticeProject\dist\practiceproject.jar" -factory practiceproject.annotprocess.MyInterfaceAnnotationProcessorFactory "D:\Variance project\PracticeProject2\src\practiceproject2\Main.java" 

L'uscita del progetto:

Called supportedAnnotationTypes........................... 
Called getProcessorFor................ 
Sum: 5000 
Sum: 500500 
+0

+1 Wowww .... Sembra interessante :-) – hsalimi

7

mi sento obbligato a dare questo codice C, dal momento che nessun altro ha ancora:

#include <stdio.h> 
int main() { 
    int x = 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+ 
      21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+ 
      41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+ 
      61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+ 
      81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100+  
      101+102+103+104+105+106+107+108+109+110+111+112+113+114+115+116+117+118+119+120+ 
      121+122+123+124+125+126+127+128+129+130+131+132+133+134+135+136+137+138+139+140+ 
      141+142+143+144+145+146+147+148+149+150+151+152+153+154+155+156+157+158+159+160+ 
      161+162+163+164+165+166+167+168+169+170+171+172+173+174+175+176+177+178+179+180+ 
      181+182+183+184+185+186+187+188+189+190+191+192+193+194+195+196+197+198+199+200+ 
      201+202+203+204+205+206+207+208+209+210+211+212+213+214+215+216+217+218+219+220+ 
      221+222+223+224+225+226+227+228+229+230+231+232+233+234+235+236+237+238+239+240+ 
      241+242+243+244+245+246+247+248+249+250+251+252+253+254+255+256+257+258+259+260+ 
      261+262+263+264+265+266+267+268+269+270+271+272+273+274+275+276+277+278+279+280+ 
      281+282+283+284+285+286+287+288+289+290+291+292+293+294+295+296+297+298+299+300+ 
      301+302+303+304+305+306+307+308+309+310+311+312+313+314+315+316+317+318+319+320+ 
      321+322+323+324+325+326+327+328+329+330+331+332+333+334+335+336+337+338+339+340+ 
      341+342+343+344+345+346+347+348+349+350+351+352+353+354+355+356+357+358+359+360+ 
      361+362+363+364+365+366+367+368+369+370+371+372+373+374+375+376+377+378+379+380+ 
      381+382+383+384+385+386+387+388+389+390+391+392+393+394+395+396+397+398+399+400+ 
      401+402+403+404+405+406+407+408+409+410+411+412+413+414+415+416+417+418+419+420+ 
      421+422+423+424+425+426+427+428+429+430+431+432+433+434+435+436+437+438+439+440+ 
      441+442+443+444+445+446+447+448+449+450+451+452+453+454+455+456+457+458+459+460+ 
      461+462+463+464+465+466+467+468+469+470+471+472+473+474+475+476+477+478+479+480+ 
      481+482+483+484+485+486+487+488+489+490+491+492+493+494+495+496+497+498+499+500+ 
      501+502+503+504+505+506+507+508+509+510+511+512+513+514+515+516+517+518+519+520+ 
      521+522+523+524+525+526+527+528+529+530+531+532+533+534+535+536+537+538+539+540+ 
      541+542+543+544+545+546+547+548+549+550+551+552+553+554+555+556+557+558+559+560+ 
      561+562+563+564+565+566+567+568+569+570+571+572+573+574+575+576+577+578+579+580+ 
      581+582+583+584+585+586+587+588+589+590+591+592+593+594+595+596+597+598+599+600+ 
      601+602+603+604+605+606+607+608+609+610+611+612+613+614+615+616+617+618+619+620+ 
      621+622+623+624+625+626+627+628+629+630+631+632+633+634+635+636+637+638+639+640+ 
      641+642+643+644+645+646+647+648+649+650+651+652+653+654+655+656+657+658+659+660+ 
      661+662+663+664+665+666+667+668+669+670+671+672+673+674+675+676+677+678+679+680+ 
      681+682+683+684+685+686+687+688+689+690+691+692+693+694+695+696+697+698+699+700+ 
      701+702+703+704+705+706+707+708+709+710+711+712+713+714+715+716+717+718+719+720+ 
      721+722+723+724+725+726+727+728+729+730+731+732+733+734+735+736+737+738+739+740+ 
      741+742+743+744+745+746+747+748+749+750+751+752+753+754+755+756+757+758+759+760+ 
      761+762+763+764+765+766+767+768+769+770+771+772+773+774+775+776+777+778+779+780+ 
      781+782+783+784+785+786+787+788+789+790+791+792+793+794+795+796+797+798+799+800+ 
      801+802+803+804+805+806+807+808+809+810+811+812+813+814+815+816+817+818+819+820+ 
      821+822+823+824+825+826+827+828+829+830+831+832+833+834+835+836+837+838+839+840+ 
      841+842+843+844+845+846+847+848+849+850+851+852+853+854+855+856+857+858+859+860+ 
      861+862+863+864+865+866+867+868+869+870+871+872+873+874+875+876+877+878+879+880+ 
      881+882+883+884+885+886+887+888+889+890+891+892+893+894+895+896+897+898+899+900+ 
      901+902+903+904+905+906+907+908+909+910+911+912+913+914+915+916+917+918+919+920+ 
      921+922+923+924+925+926+927+928+929+930+931+932+933+934+935+936+937+938+939+940+ 
      941+942+943+944+945+946+947+948+949+950+951+952+953+954+955+956+957+958+959+960+ 
      961+962+963+964+965+966+967+968+969+970+971+972+973+974+975+976+977+978+979+980+ 
      981+982+983+984+985+986+987+988+989+990+991+992+993+994+995+996+997+998+999+1000; 
    printf("%d\n", x); 
} 

E tutto quello che devo fare è controllare l'assemblaggio per trovare la risposta!

gcc -S compile_sum.c; 
grep "\$[0-9]*, *-4" compile_sum.s 

E vedo:

movl $500500, -4(%rbp) 
+0

Caratteristica di un'implementazione specifica, non del linguaggio C. – Puppy

+3

Quanti compilatori ** C conosci che non sono una "implementazione specifica" di C? –

+0

Nota: questo approccio funziona nella maggior parte delle lingue. –

1

utilizzando Java si può fare una cosa simile al C# risposta:

public class Cheat { 
    public static final int x = (1000 *1001/2); 
} 

javac -Xprint Cheat.java 

public class Cheat { 

    public Cheat(); 
    public static final int x = 500500; 
} 

si può fare questo in scala using peano numbers perché si può forzare il compilatore per fare la ricorsione, ma non credo che si può fare la stessa cosa in C#/java

anoth er soluzione che non utilizza -Xprint ma ancora più dubbia

public class Cheat { 
    public static final int x = 5/(1000 *1001/2 - 500500); 
} 

javac -Xlint:all Cheat.java 

Cheat.java:2: warning: [divzero] division by zero 
    public static final int x = 5/(1000 *1001/2 - 500500); 
          ^
1 warning 

senza utilizzare alcun flag di compilazione. dal momento che è possibile verificare un numero arbitrario di costanti (non solo 500500) questa soluzione dovrebbe essere accettabile.

public class Cheat { 
    public static final short max = (Short.MAX_VALUE - 500500) + 1001*1000/2; 
    public static final short overflow = (Short.MAX_VALUE - 500500 + 1) + 1001*1000/2; 

} 

Cheat.java:3: error: possible loss of precision 
    public static final short overflow = (Short.MAX_VALUE - 500500 + 1) + 1001*1000/2; 
                   ^
    required: short 
    found: int 
1 error 
+0

Non hai guidato il compilatore su * compute * '500500', mi dispiace. – Xeo

+0

è questo in riferimento a tutte e tre le soluzioni? nella soluzione 1 ho preso un po 'di codice java e l'ho compilato e il compilatore ha stampato 500500. Che assomiglia molto al compiler computing 500500. Come è possibile che non compili il compilatore 500500? – benmmurphy

+0

Sì, è vero, stavo parlando delle soluzioni 2 e 3. Ho letto questa risposta già su un aggiornamento precedente e sono tornata su quella più recente e in qualche modo sembra aver dimenticato la prima soluzione. – Xeo

4

estesa dalla risposta di Carl Walsh effettivamente stampare il risultato durante la compilazione:

#define VALUE (1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+\ 
21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+\ 
41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+\ 
61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+\ 
81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100+\ 
101+102+103+104+105+106+107+108+109+110+111+112+113+114+115+116+117+118+119+120+\ 
121+122+123+124+125+126+127+128+129+130+131+132+133+134+135+136+137+138+139+140+\ 
141+142+143+144+145+146+147+148+149+150+151+152+153+154+155+156+157+158+159+160+\ 
161+162+163+164+165+166+167+168+169+170+171+172+173+174+175+176+177+178+179+180+\ 
181+182+183+184+185+186+187+188+189+190+191+192+193+194+195+196+197+198+199+200+\ 
201+202+203+204+205+206+207+208+209+210+211+212+213+214+215+216+217+218+219+220+\ 
221+222+223+224+225+226+227+228+229+230+231+232+233+234+235+236+237+238+239+240+\ 
241+242+243+244+245+246+247+248+249+250+251+252+253+254+255+256+257+258+259+260+\ 
261+262+263+264+265+266+267+268+269+270+271+272+273+274+275+276+277+278+279+280+\ 
281+282+283+284+285+286+287+288+289+290+291+292+293+294+295+296+297+298+299+300+\ 
301+302+303+304+305+306+307+308+309+310+311+312+313+314+315+316+317+318+319+320+\ 
321+322+323+324+325+326+327+328+329+330+331+332+333+334+335+336+337+338+339+340+\ 
341+342+343+344+345+346+347+348+349+350+351+352+353+354+355+356+357+358+359+360+\ 
361+362+363+364+365+366+367+368+369+370+371+372+373+374+375+376+377+378+379+380+\ 
381+382+383+384+385+386+387+388+389+390+391+392+393+394+395+396+397+398+399+400+\ 
401+402+403+404+405+406+407+408+409+410+411+412+413+414+415+416+417+418+419+420+\ 
421+422+423+424+425+426+427+428+429+430+431+432+433+434+435+436+437+438+439+440+\ 
441+442+443+444+445+446+447+448+449+450+451+452+453+454+455+456+457+458+459+460+\ 
461+462+463+464+465+466+467+468+469+470+471+472+473+474+475+476+477+478+479+480+\ 
481+482+483+484+485+486+487+488+489+490+491+492+493+494+495+496+497+498+499+500+\ 
501+502+503+504+505+506+507+508+509+510+511+512+513+514+515+516+517+518+519+520+\ 
521+522+523+524+525+526+527+528+529+530+531+532+533+534+535+536+537+538+539+540+\ 
541+542+543+544+545+546+547+548+549+550+551+552+553+554+555+556+557+558+559+560+\ 
561+562+563+564+565+566+567+568+569+570+571+572+573+574+575+576+577+578+579+580+\ 
581+582+583+584+585+586+587+588+589+590+591+592+593+594+595+596+597+598+599+600+\ 
601+602+603+604+605+606+607+608+609+610+611+612+613+614+615+616+617+618+619+620+\ 
621+622+623+624+625+626+627+628+629+630+631+632+633+634+635+636+637+638+639+640+\ 
641+642+643+644+645+646+647+648+649+650+651+652+653+654+655+656+657+658+659+660+\ 
661+662+663+664+665+666+667+668+669+670+671+672+673+674+675+676+677+678+679+680+\ 
681+682+683+684+685+686+687+688+689+690+691+692+693+694+695+696+697+698+699+700+\ 
701+702+703+704+705+706+707+708+709+710+711+712+713+714+715+716+717+718+719+720+\ 
721+722+723+724+725+726+727+728+729+730+731+732+733+734+735+736+737+738+739+740+\ 
741+742+743+744+745+746+747+748+749+750+751+752+753+754+755+756+757+758+759+760+\ 
761+762+763+764+765+766+767+768+769+770+771+772+773+774+775+776+777+778+779+780+\ 
781+782+783+784+785+786+787+788+789+790+791+792+793+794+795+796+797+798+799+800+\ 
801+802+803+804+805+806+807+808+809+810+811+812+813+814+815+816+817+818+819+820+\ 
821+822+823+824+825+826+827+828+829+830+831+832+833+834+835+836+837+838+839+840+\ 
841+842+843+844+845+846+847+848+849+850+851+852+853+854+855+856+857+858+859+860+\ 
861+862+863+864+865+866+867+868+869+870+871+872+873+874+875+876+877+878+879+880+\ 
881+882+883+884+885+886+887+888+889+890+891+892+893+894+895+896+897+898+899+900+\ 
901+902+903+904+905+906+907+908+909+910+911+912+913+914+915+916+917+918+919+920+\ 
921+922+923+924+925+926+927+928+929+930+931+932+933+934+935+936+937+938+939+940+\ 
941+942+943+944+945+946+947+948+949+950+951+952+953+954+955+956+957+958+959+960+\ 
961+962+963+964+965+966+967+968+969+970+971+972+973+974+975+976+977+978+979+980+\ 
981+982+983+984+985+986+987+988+989+990+991+992+993+994+995+996+997+998+999+1000) 

char tab[VALUE]; 

int main() 
{ 
    tab = 5; 
} 

uscite GCC:

test.c: In function 'main': 
test.c:56:9: error: incompatible types when assigning to type 'char[500500]' fro 
m type 'int' 
0

Anche se questo in realtà lavora con piccoli numeri, clang ++ mi restituisce un compilatore errore se sto usando sum_first dove N> 400.

#include <iostream> 

using namespace std; 


template <int N> 
struct sum_first 
{ 
    static const int value = N + sum_first<N - 1>::value; 
}; 

template <> 
struct sum_first<0> 
{ 
    static const int value = 0; 
}; 

int main() 
{ 
    cout << sum_first<1000>::value << endl; 
} 
Problemi correlati