Autor Wątek: Zagadki językoznawcze  (Przeczytany 59805 razy)

Offline Kuba D.

  • Użytkownik

# Październik 14, 2009, 18:04:14
Zagadka na dziś, sponsorowana przez Insanely Low-Level: Oto (błędny) kod C++.

Kod: (cpp) [Zaznacz]
template <class T> class bugs {
};

template<> bugs<int>::bugs()
{
}

Pytanie brzmi: Jaki error rzuci MSVC? ^^

MSVC 2008 EE:
Cytuj
fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'msc1.cpp', line 1411)

Ech... Nie zrozumiałeś zabawy. Masz odgadnąć  ten error a nie sprawdzić w MSVC i zapodać go tu ;)

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline lgromanowski

  • Użytkownik
    • OpenMW, Elderscrolls III: Morrowind engine reimplementation

# Październik 14, 2009, 18:10:12
Ech... Nie zrozumiałeś zabawy. Masz odgadnąć  ten error a nie sprawdzić w MSVC i zapodać go tu ;)

Jakbym znał źródła MSVC, to być może bym się pokusił o zgadywanie jaki się błąd pojawi, a ponieważ nie znam, to sprawdzam empirycznie ;]

Offline MadBonsai

  • Użytkownik
    • Ifrit

# Październik 15, 2009, 00:37:19
Zapoznaj się więc z pierwszym postem  ;)
Cytuj
+ Nie stosujemy kompilatorów do odpowiedzi (!) Odpowiadajmy na podstawie wiedzy a nie, "wklepałem do IDE i zadziałało tak, więc musi być tak". Zawsze trzeba uargumentować odpowiedź: dlaczego dzieje się tak, a nie inaczej.

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 15, 2009, 03:26:44
Cytuj
+ Nie stosujemy kompilatorów do odpowiedzi (!) Odpowiadajmy na podstawie wiedzy a nie, "wklepałem do IDE i zadziałało tak, więc musi być tak". Zawsze trzeba uargumentować odpowiedź: dlaczego dzieje się tak, a nie inaczej.
W takim razie niech będzie coś dla prawdziwych hardkorów ode mnie: ;)


Zagadka: co robi poniższa funkcja? ;) ;) ;)
int foo(int x)
{
    static int t[]={
        0,11,0,-1,1,0,0,0,0,65536,1,6,2,6,2,7,2,7,2,9,2,2,2,7,2,8,2,8,2,2,2,2,2,
        4,2,7,2,2,2,2,2,3,2,8,2,2,2,2,2,4,2,7,2,2,2,2,2,4,2,7,8,2,2,2,2,3,-28,7,
        2,7,2,8,2,2,2,7,2,2,2,2,2,7,2,2,2,6,2,2,2,2,2,5,2,5,2,6,2,2,2,5,2,8,2,8,
        2,2,2,2,2,4,2,5,2,2,2,2,2,6,2,2,2,8,2,2,2,2,2,4,2,5,8,2,2,2,2,3,-22,2,2,
        2,2,4,2,8,2,2,2,2,2,0,2,8,10,2,2,2,2,7,2,6,2,8,2,8,2,10,2,2,2,8,2,2,2,2,
        2,7,2,8,-152,0,2,0,2,6,2,2,2,0,2,2,2,2,2,3,-193
    };
    for(int i=(t[0]=x,t[1]);i+=(x=t[t[i]]-=x)<0?t[i+1]:2;);
    return *t;
}

Offline ConayR

  • Użytkownik

# Październik 15, 2009, 03:59:16
Zagadka: co robi poniższa funkcja? ;) ;) ;)
Serio oczekujesz, że ktoś to przetrawi bez kompilatora? ;)

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 15, 2009, 04:50:21
Serio oczekujesz, że ktoś to przetrawi bez kompilatora? ;)
No cóż, macie zabawę. ;) W odróżnieniu od poprzedniego to akurat jest chociaż wykonalne. :)

flaczki

  • Gość
# Październik 15, 2009, 10:45:42
foo(0) pewnie zwróci 0. Gorzej gdy będzie foo(3) albo foo(9). Pewnie jakiś błąd podczas wykonania.

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 15, 2009, 11:12:37
foo(0) pewnie zwróci 0. Gorzej gdy będzie foo(3) albo foo(9). Pewnie jakiś błąd podczas wykonania.
Nie ma żadnych błędów wykonania. Zapewniam. :)

flaczki

  • Gość
# Październik 15, 2009, 11:24:42
foo(0) pewnie zwróci 0. Gorzej gdy będzie foo(3) albo foo(9). Pewnie jakiś błąd podczas wykonania.
Nie ma żadnych błędów wykonania. Zapewniam. :)

Generalnie wszystko zależy od tego jak wykona się ten fragment:
int i=(t[0]=x,t[1])Jeżeli kolejność będzie:
i = t[0] a następnie t[0] = x
to sprawa jest jasna.
Jeżeli odwrotnie to dla niektórych x program powinien się wyłożyć.

Offline Xion

  • Moderator
    • xion.log

# Październik 15, 2009, 11:30:40
Kolejność wykonania operandów przecinka jest niezdefiniowana. A jeśli Krzysiek twierdzi że program wykona się poprawnie zawsze, to pewnie nie w tym rzecz.

Tak czy owak, bez kompilatora nawet nie chce mi się do tego podchodzić ;)

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 15, 2009, 11:45:24
Cytuj
Kolejność wykonania operandów przecinka jest niezdefiniowana.
Nie zdarzyło mi się jeszcze, żeby kolejność była inna niż "normalna". W tym przypadku jednak kolejność nie ma przecież żadnego znaczenia.

Cytuj
Tak czy owak, bez kompilatora nawet nie chce mi się do tego podchodzić ;)
Bez kompilatora może być nawet łatwiej. ;) O ile z kompilatorem dość szybko można pewnie wpaść na to, co ta funkcja robi, zawsze pozostaje pytanie "jak" ona to robi i dlaczego działa. ;)

flaczki

  • Gość
# Październik 15, 2009, 12:19:09
Spróbuję jeszcze raz:

int i = (t[0] = x, t[1])
   t[0] = x
   t[1]
   wartość wyrażenia w nawiasie to t[1]
   i = 11

i+=(x = t[t] -= x)<0?t[i+1]:2
   i+=(x = t[t] -= x) // assignment expression
      ze względu na nawias->
      x = t[t[11]] // następne assignment expression
      x = t[6]
      x = 0

      x -= x // następne assignment expression
      x = 0

      wartosc wyrazenia w nawiasie równa się 0
   
      i+=()
      i+=0
      i = 11

   11<0 false
   tzn. wartosc całego i+=(x = t[t] -= x)<0?t[i+1]:2 równa się 2

Kolejny obrót pętli znowu dla i = 11

Z tego wynikałoby, że pętla będzie wykonywała się w nieskonczoność.
Przy okazji w t[0] będzie wartość x.

EDIT: Już wiem, że źle (uruchomiłem i wiem co będzie zwracać foo). Generalnie poddaję się.  :)
« Ostatnia zmiana: Październik 15, 2009, 12:24:26 wysłana przez flaczki »

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 15, 2009, 12:27:19
Cytuj
      i+=()
      i+=0
      i = 11
Polecam odświeżyć sobie priorytety operacji. ;)

flaczki

  • Gość
# Październik 15, 2009, 13:04:34
Cytuj
      i+=()
      i+=0
      i = 11
Polecam odświeżyć sobie priorytety operacji. ;)

Zgadza się. Dzięki. Teraz już mam rozwiązanie zgodne z rzeczywistością (dodatkowo sprawdziłem z plikiem asm  :) ).

Mam nadzieję, że zaliczyłem te zajęcia chociaż na 3+  ;)

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 15, 2009, 13:46:03
Nie ma co sie poddawać - wystarczy że pomysli się logicznie, co robi jeden obieg pętli, a potem przejrzy dane, na których pracuje. :)