/ / Czy makra nie są gwarantowane? - c ++, c

Czy makra gwarantują brak nadwyżki? - c ++, c

Jako programista nauczyłem się preferować słowo kluczowe inline do definicji makr dla małych funkcji. Wiem, że wiadomo, że inline jest bardziej bezpieczny ze względu na definicje makr, które nie sprawdzają typu, jednak powiedziano mi, że inline jest tylko żądaniem, aby kompilator faktycznie zastąpił kod, a kompilator nie musi zaakceptować tego żądania więc zastanawiam się, czy są również żądania makr, czy też nie mają zagwarantowanego czasu pracy?

Odpowiedzi:

8 dla odpowiedzi № 1

Makra są wcześniej zastępowane tekstemkrok kompilacji - nie mogą mieć „czasu działania” w sposób, w jaki mogłaby wywołać funkcję. Nie jest to jednak wystarczający powód, aby używać makr zamiast funkcji, ponieważ kompilatory automatycznie wstawiają funkcje nawet bez inline słowo kluczowe z włączonymi optymalizacjami. Ponadto, korzystając z optymalizacji czasu łącza -flto pozwoli na wstawianie między TU.


2 dla odpowiedzi nr 2

Makra to rzeczy do kompilacji. Nigdy nie pojawiają się jako makra w skompilowanym kodzie. Jeśli zdefiniujesz coś takiego

#define MyVar 5

I robisz to w kodzie:

double y = MyVar*MyVar;

To jest dokładnie tak:

double y = 5*5;

W czasie kompilacji MyVar makro jest zastąpiony o zdefiniowaną wartość. W czasie wykonywania nie ma absolutnie żadnego obciążenia.


1 dla odpowiedzi nr 3

Makra są funkcją preprocesora.

Preprocesor modyfikuje program w sposób czysto tekstowy, a wyniki można zobaczyć, jeśli uruchomisz preprocesor oddzielnie.

Z gcc możesz to zrobić za pomocą albo gcc -E lub cpp. Robię to dość często, gdy debuguję moje makra.

Przykład main.c:

#include <stdio.h>

#define MC_repeat(X)  
for(int _i=0;_i<(X);_i++)

#define rt return

#define MC_xputs(X) if(0>puts(X)) rt -1;


int main()
{
MC_repeat(5)
MC_xputs("hello world");
rt 0;
}

Wyjście z gcc -E main.c | tail:

# 2 "main.c" 2
# 11 "main.c"

# 11 "main.c"
int main()
{
for(int _i=0;_i<(5);_i++)
if(0>puts("hello world")) return -1;;
return 0;
}

Kiedy kompilujesz takie źródło, jest to tak, jakbyś najpierw uruchomił preprocesser, a następnie przesłał wyniki do właściwego kompilatora.

gcc tak naprawdę nie robi tego w ten sposób (więc otrzymujesz lepsze komunikaty o błędach), ale możesz zmusić go do:

#actually pipes preprocessor output to the compiler proper
gcc -E main.c | gcc -x cpp-output