#define Konvertierung von C nach C #

8

Ist das C-Code:

%Vor%

Ссылка

Entspricht dieser C # -Code?

%Vor%

?

    
Danpe 29.08.2011, 12:09
quelle

6 Antworten

13

nein. beachte Folgendes:

LERP(x++,1,2);

Der c-Code kann auch einen Nebeneffekt haben, x zweimal zu erhöhen [er ist nicht definiert, wie von @phoresel erwähnt], während der c # -Code perfekt definiert ist und x nur einmal erhöht.

Das Ergebnis könnte auch anders sein, da der erste a und der zweite [im Makro] möglicherweise einen anderen Wert haben, da er in der ersten möglicherweise erhöht wurde.

    
amit 29.08.2011, 12:13
quelle
8

Nein. Die C-Variante kommt mit allen Mängeln von #define -Makros. Erinnerung:

%Vor%


Mögliche Leistungsverschwendung

Stellen Sie sich einen reinen Funktionsaufruf in einem Aufruf von #define -macro vor:

%Vor%

Diese Zeile erweitert sich zu:

%Vor%

Jetzt haben Sie möglicherweise die Laufzeit für zwei Aufrufe Ihrer Fakultätsfunktion verdoppelt, die vorher nur eine war.

Das wird sicherlich noch schlimmer, wenn Sie Ihr Lerping verschachteln, wie es zum Beispiel in einigen Grafikprogrammierungssituationen üblich ist:

%Vor%

Erweitern zu:

%Vor%

Erweitern zu (Formatierung wurde zur besseren Lesbarkeit optimiert):

%Vor%

Während die saubere Version rechnerisch nicht mehr als:

%Vor%

oder

%Vor%

Also in einem zweidimensionalen Setup

  1. Richtige Version:
    1. 4 Aufrufe an fac()
    2. 4 Ergänzungen
    3. 2 Multiplikationen
  2. '# define' Version:
    1. 9 Aufrufe an fac()
    2. 8 Ergänzungen
    3. 4 Multiplikationen

Es wird mit jeder hinzuzufügenden Dimension exponentiell schlechter. Manchmal wird sogar ein fünfdimensionales Perlin Noise angezeigt (3D Volumen + Zeit + kontinuierlicher Startwert), < a href="http://ideone.com/8YkeM"> für die einige Ausdrücke ausgewertet werden, die 31 Mal statt nur einmal ausflippen! :

%Vor%

Sie können den vorverarbeiteten Code auch anzeigen, indem Sie cpp aufrufen (beachten Sie die einzelne Darstellung von probe() vorher).

%Vor%
  

[Schnipsel] (((((((911) - (910)) * (912) + (910))) ((((98) - (97)) * (99) + (97)))) * (913) + ((((98) - (97)) * (99) + (97))))) - ((((((94) - (93)) * (95) + (93))) - (((91) - (90)) * (92) + (90)))) * (96) + ((((91) - ( 90)) * (92) + (90)))))) * (914) + ((((((94) - (93)) * (95) + (93))) - (((( 91) - (90)) * (92) + (90)))) * (96) + ((((91) - (90)) * (92) + (90))))))) - ( (((((11) - (10)) * (12) + (10))) - (((8) - (7)) * (9) + (7)))) * (13) + (((8) - (7)) * (9) + (7))))) - ((((((4) - (3)) * (5) + (3) )) - ((((1) - (0)) * (2) + (0)))) * (6) + ((((1) - (0)) * (2) + (0)) )))) * (14) + ((((((4) - (3)) * (5) + (3))) - ((((1) - (0)) * (2) + (0)))) * (6) + ((((1) - (0)) * (2) + (0)))))))) * (1014) + ((((((((((( ((11) - (10)) * (12) + (10))) - (((8) - (7)) * (9) + (7)))) * (13) + ((( (8) - (7)) * (9) + (7))))) - ((((((4) - (3)) * (5) + (3))) - (((( 1) - (0)) * (2) + (0)))) * (6) + ((((1) - (0)) * (2) + (0)))))) * (14 ) + ((((((4) - (3)) * (5) + (3))) - ((((1) - (0)) * (2) + (0)))) * (6) + ((((1) - (0)) * (2) + (0))))))))) - (((((((911) - (910)) * (912) + (910))) - (((98) - (97)) * (99) + (97)))) * (913) + ((((98) - (97)) * ( 99) + (97))))) - (((((94) - (93)) * (95) + (93))) - (((91) - (90)) * (92 ) + (90)))) * (96) + ((((91) - (90)) * (92) + (90)))))) * (914) + (((((( ) - (93)) * (95) + (93))) - (((91) - (90)) * (92) + (90)))) * (96) + ((((91) - (90)) * (92) + (90))))))) - ((((((11) - (10)) * (12) + (10))) - ((( ((8) - (7)) * (9) + (7)))) * (13) + ((((8) - (7)) * (9) + (7))))) - ( (((((4) - (3)) * (5) + (3))) - ((((1) - (Sonde ())) * (2) + (Sonde ())))) * (6) + ((((1) - (Sonde ())) * (2) + (Sonde ()))))) * (14) + ((((((4) - (3 )) * (5) + (3))) - ((((1) - (Sonde ())) * (2) + (Sonde ())))) * (6) + ((((1) - (Sonde ())) * (2) + (Sonde ())))))))) * (1014) + ((((((11) - (10)) * (12) + (10))) - (((8) - (7)) * (9) + (7)))) * (13) + ((((8) - (7)) * (9) + (7))))) - ((((((4) - (3)) * (5) + (3))) - ((((1) - (Sonde ())) * (2) + (Sonde ())))) * (6) + ((((1) - (Sonde ())) * (2) + (Sonde ())))))) * (14) + ((((((4) - (3)) * (5) + (3))) - (((( ) - (Sonde ())) * (2) + (Sonde ())))) * (6) + ((((1) - (Sonde ())) * (2) + (Sonde ())) ))))))))) * (666) + ((((((911) - (910)) * (912) + (910))) - (((98) - (97)) * (99) + (97)))) * (913) + ((((98) - (97)) * (99) + (97))))) - ((( ((94) - (93)) * (95) + (93))) - (((91) - (90)) * (92) + (90)))) * (96) + ((( (91) - (90)) * (92) + (90)))))) * (914) + ((((((94) - (93)) * (95) + (93))) - (((91) - (90)) * (92) + (90)))) * (96) + ((((91) - (90)) * (92) + (90)))) ))) - (((((11) - (10)) * (12) + (10))) - ((((8) - (7)) * (9) + (7 )))) * (13) + ((((8) - (7)) * (9) + (7))))) - ((((((4) - (3)) * (5 ) + (3))) - ((((1) - (Sonde ())) * (2) + (Sonde ())))) * (6) + ((((1) - (Sonde () )) * (2) + (Sonde ())))))) * (14) + ((((((4) - (3)) * (5) + (3))) - ((( (1) - (Sonde ())) * (2) + (Sonde ())))) * (6) + ((((1) - (Sonde ())) * (2) + (Sonde () )))))))) * (1014) + ((((11) - (10)) * (12) + (10))) - (((8) - (7 )) * (9) + (7)))) * (13) + (( ((8) - (7)) * (9) + (7))))) - ((((((4) - (3)) * (5) + (3))) - ((( (1) - (Sonde ())) * (2) + (Sonde ())))) * (6) + ((((1) - (Sonde ())) * (2) + (Sonde () )))))) * (14) + ((((((4) - (3)) * (5) + (3))) - ((((1) - (Sonde ())) * (2) + (Sonde ())))) * (6) + ((((1) - (Sonde ())) * (2) + (Sonde ()))))))))))

Wieder volle Quelle ist hier .


Potentielles undefiniertes Verhalten

Du kannst böses Zeug hineinlegen:

%Vor%

, das zu

erweitert wird %Vor%

ist undefiniertes Verhalten in C¹ (und in C ++, btw). a könnte zweimal erhöht werden, oder es könnte einmal erhöht werden, oder es wird eine Ausnahme ausgelöst, die Debug-Runtime-Exception: Invoked Undefined Behaviour sagt, oder der Compiler ist schlau genug, um diesen Code oder was auch immer abzulehnen.

Das undefinierte Verhalten ergibt sich aus der Tatsache, dass der C99-Standard (und auch C ++ 2003) es nicht erlaubt, einen Wert mehrfach zu ändern, bevor er die nächste Sequenzpunkt .


ID Verschmutzung und Infektion

(Dies ist besonders relevant, wenn Sie die C # in die Makrovariante konvertieren.)

Der #define -macro-name verschmutzt und infiziert die gesamte Übersetzungseinheit vom Definitionspunkt bis zum Ende der Einheit oder ihrer Undefinition.

%Vor%

Mehr ...

  • Makros sind generisch, aber nicht typsicher. Der Makro-Writer hat keine (saubere) Möglichkeit, Einschränkungen für die Typen festzulegen, für die das Makro gültig sein soll.
  • Makros haben keinen Gültigkeitsbereich, obwohl dies bereits im letzten Abschnitt
  • impliziert ist

¹: C99 (ISO / IEC 9899: TC2), J.2, "Undefiniertes Verhalten": Between two sequence points, an object is modified more than once, or is modified and the prior value is read other than to determine the value to be stored (6.5).

    
Sebastian Mach 29.08.2011 12:38
quelle
5

Technisch gesehen sind sie nicht gleich. Das C-Makro kann einen beliebigen Typ annehmen: int , float , byte , usw.

Ihre C # -Version kann nur mit doppelten, ohne explizite Umwandlungen umgehen. Sie müssen bei Bedarf für andere Typen Überladungen hinzufügen.

    
CodeNaked 29.08.2011 12:14
quelle
2

Es ist grundsätzlich äquivalent, ja. Sie können auch einige Klammern loswerden:

%Vor%     
Andrea Bergia 29.08.2011 12:12
quelle
2

Um zu bekommen, was Sie in C hatten, können Sie verwenden:

%Vor%

Aber ich stimme mit amit überein. Das könnte das gleiche sein, das Sie in C hatten (aber nur für double, nicht für andere Typen), aber es könnte nicht das sein, was Sie wirklich wollen .. (mit Delegate können Sie 'i ++' als ein, nicht nur i ++) setzen

    
rudolf_franek 29.08.2011 12:28
quelle
1

Ja, aber Sie können es einfacher schreiben:

%Vor%     
Alex F 29.08.2011 12:12
quelle

Tags und Links