Sizeof 'A' (war Cidiosyncracies)

Schnelle objektorientierte, kompilierende Programmiersprache.
mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von mfro » Do Feb 20, 2014 6:07 pm

Xin hat geschrieben:
mfro hat geschrieben:Joker-Frage: warum gibt auch der standardkonformste und penibelste Compiler trotz "-Wall" keine Warnung aus, obwohl man eine char Variable (die ja nur 8 Bits hat) um 9 Bits shiftet?
Keine Ahnung, aber nur weil das Ergebnis sich nicht mehr ändert, wird die Aufgabe doch nicht falsch!? Ein Compiler meckert - denke ich - auch nicht, wenn man c *= 1 oder c += 0 schreibt.

Lass Dir mit der Antwort mehr Zeit - damit auch andere eine Schätzung abgeben können.
Nachdem offensichtlich sonst keiner mitspielen will:

eine Warnung kommt deswegen nicht, weil tatsächlich nicht mehr Bits geshiftet werden, als die Variable Bits hat.

Auch hier findet (durch den Shift-Operator) eine integer promotion statt: vor dem Shiften wird die Variable auf 32 Bit erweitert und das Ergebnis geshiftet. Anschließend werden die überflüssigen Bits abgeschnitten.

Probiert's aus: der Compiler bringt die Warnung erst, wenn mehr als 31 Bits geshiftet werden.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von mfro » Do Feb 20, 2014 11:12 pm

Mal was anderes:

Code: Alles auswählen

    int i = 2 - - - - - - 2;
    printf("%d\n", i);

Darf man das? Falls ja, was kommt wohl raus?
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
oenone
Beiträge: 223
Registriert: Do Sep 01, 2011 2:42 pm
Wohnort: Bremen
Kontaktdaten:

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von oenone » Di Feb 25, 2014 4:09 pm

klar darf man das und es kommt 4 raus, da -(-2) = +2.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von Xin » Di Feb 25, 2014 6:11 pm

Würde oenone zustimmen.
Für den Compiler sollte da int i = 2 - ( -( -( -( -( -2 ))))) stehen. ( -( -( -( -( -2 ))))) sind ( -2 ) und 2-(-2) sind 4.

Ähnlich

Code: Alles auswählen

bool b = !!!!!!i;
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von cloidnerux » Di Feb 25, 2014 6:18 pm

Was wird wohl

Code: Alles auswählen

int a = 1;
    a ^= (a++ + --a) * a++;
liefern?
Redundanz macht wiederholen unnötig.
quod erat expectandum

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von mfro » Di Feb 25, 2014 6:34 pm

cloidnerux hat geschrieben:Was wird wohl

Code: Alles auswählen

int a = 1;
    a ^= (a++ + --a) * a++;
liefern?
Das darf alles liefern was es will und - wenn es denn will - deinen Rechner in die Luft sprengen und/oder im Kreml ein paar Nuklearraketen starten: das Ergebnis ist undefiniert.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von mfro » Mo Mär 10, 2014 10:11 pm

Kennt jemand das Ding hier:

Code: Alles auswählen

void copy(int *to, int *from, int count)
{
    int n = (count + 7) / 8;
    switch (count % 8)
    {
        case 0:
            do
            {
                *to = *from++;
        case 7:         *to = *from++;
        case 6:         *to = *from++;
        case 5:         *to = *from++;
        case 4:         *to = *from++;
        case 3:         *to = *from++;
        case 2:         *to = *from++;
        case 1:         *to = *from++;
                        } while (--n>0);
    }
}
?? Das sieht möglicherweise ein wenig komisch aus. Darf man das?
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von cloidnerux » Mo Mär 10, 2014 10:40 pm

?? Das sieht möglicherweise ein wenig komisch aus. Darf man das?
Es sieht mehr als komisch aus, Visual Studio akzeptiert es aber.
Anscheinend ist das Scoping bei switch etwas anders.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von Xin » Mo Mär 10, 2014 11:47 pm

mfro hat geschrieben:Kennt jemand das Ding hier:
?? Das sieht möglicherweise ein wenig komisch aus. Darf man das?
Kennen tue ich es nicht, ich gehe davon aus, dass hier *to++ gemeint ist, dann verstehe ich den Zweck: Es werden immer 8 ints ohne Fragen kopiert, in der ersten Runde werden die ints, die zuviel sind, kopiert.

Es könnte funktionieren, weil keine lokale Variable deklariert wird - also auch keine zerstört wird... dann könnte man von "dürfen" sprechen. Eine wirklich gute Idee erscheint mir der Algorithmus so nicht zu sein, weil im Prinzip zwei Abschnitte des Algorithmus' zusammengeworfen werden.
Die case-Marken werden vom Compiler letztendlich nur in Adressen übersetzt und wo die letztendlich liegen spielt eigentlich keine Rolle, solange sie innerhalb eines Switches liegen.
Ich den Algorithmus also als richtig (bei *to++) ansehen unter der Bedingung, dass das while keine Variablen auf den Stack legt.
Ob man das deswegen darf... darf bezweifelt werden. Indiz dafür wäre, dass die Compiler es fressen, denn es wäre leichter "Nein" zu sagen, als in höher gelegenen Scopes nach dem Switch zu suchen...
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Sizeof 'A' (war Cidiosyncracies)

Beitrag von mfro » Di Mär 11, 2014 12:03 am

*to ist korrekt, weil das Original hier auf eine Hardware-Adresse geschrieben hat.

Der Code ist völlig korrektes und konformes C (auch nach "modernen Maßstäben" und Standards), die Idee ist "loop unrolling".

Braucht heute keiner mehr (außer, um die Leute zu verblüffen), aber zu der Zeit, als es noch nicht so gut optimierende Compiler gab, war das wirklich zu etwas nütze.

Einen Namen hat das ganze auch: nach seinem Erfinder: Duff's Device. Wie man auf so was verqueres kommt, weiß ich auch nicht :D
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Antworten