Funkcje wbudowane a makra preprocesora

Czym funkcja inline różni się od makra preprocesora?

Author: Jim Fell, 2009-07-16

13 answers

Makra preprocesora są tylko wzorcami substytucji zastosowanymi do kodu. Mogą być używane niemal wszędzie w kodzie, ponieważ są zastępowane rozszerzeniami przed rozpoczęciem kompilacji.

Funkcje Inline są funkcjami rzeczywistymi, których ciało jest bezpośrednio wstrzykiwane do ich miejsca wywołania. Mogą być używane tylko wtedy, gdy odpowiednie jest wywołanie funkcji.

Teraz, jeśli chodzi o używanie makr a funkcji inline w kontekście podobnym do funkcji, należy pamiętać, że:

  • makra nie są bezpieczne dla typów i mogą być rozszerzane niezależnie od tego, czy są poprawne składniowo - Faza kompilacji będzie zgłaszać błędy wynikające z problemów z rozbudową makr.
  • makra mogą być używane w kontekście, w którym się nie spodziewasz, co powoduje problemy
  • makra są bardziej elastyczne, ponieważ mogą rozszerzać inne makra - podczas gdy funkcje wbudowane niekoniecznie to robią.
  • makra mogą powodować skutki uboczne z powodu ich ekspansji, ponieważ wyrażenia wejściowe są kopiowane wszędzie tam, gdzie pojawiają się we wzorze.
  • funkcja Inline nie zawsze jest gwarantowana - niektóre Kompilatory robią to tylko w release buildach lub gdy są specjalnie skonfigurowane do tego celu. Ponadto, w niektórych przypadkach inlining może nie być możliwe.
  • Funkcje Inline mogą zapewnić zakres dla zmiennych (szczególnie statycznych), makra preprocesora mogą to robić tylko w blokach kodu {...}, A zmienne statyczne nie zachowają się dokładnie tak samo.
 117
Author: LBushkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 14:23:57

Po pierwsze, makra preprocesora są po prostu "kopiuj wklej" w kodzie przed kompilacją. Nie ma więc sprawdzania typu , a niektóre efekty uboczne mogą się pojawić

Na przykład, jeśli chcesz porównać 2 wartości:

#define max(a,b) ((a<b)?b:a)

Działania niepożądane pojawiają się, jeśli zastosujesz max(a++,b++) na przykład (a lub b będą zwiększane dwukrotnie). Zamiast tego użyj (na przykład)

inline int max( int a, int b) { return ((a<b)?b:a); }
 67
Author: ThibThib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 13:36:50

Kluczową różnicą jest sprawdzanie typu. Kompilator sprawdzi, czy to, co przekazujesz jako wartości wejściowe, należy do typów, które można przekazać do funkcji. Nie jest to prawdą w przypadku makr preprocesora - są one rozszerzane przed jakimkolwiek sprawdzaniem typu, co może powodować poważne i trudne do wykrycia błędy.

Tutaj {[4] } jest kilka innych mniej oczywistych punktów nakreślonych.

 12
Author: sharptooth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 13:27:34

Funkcje Inline są rozszerzane przez kompilator, gdzie jako makra są rozszerzane przez preprocesor, co jest zwykłą substytucją tekstową.Stąd

  • Nie ma sprawdzania typu podczas wywoływania makra, podczas gdy sprawdzanie typu odbywa się podczas wywoływania funkcji.

  • Niepożądane wyniki i nieefektywność mogą wystąpić podczas ekspansji makr z powodu ponownej oceny argumentów i kolejności operacji. Na przykład

    #define MAX(a,b) ((a)>(b) ? (a) : (b))
    int i = 5, j = MAX(i++, 0);
    

    Spowodowałoby w

    int i = 5, j = ((i++)>(0) ? (i++) : (0));
    
  • Argumenty makr nie są oceniane przed rozszerzeniem makra

    #define MUL(a, b) a*b
    int main()
    {
      // The macro is expended as 2 + 3 * 3 + 5, not as 5*8
      printf("%d", MUL(2+3, 3+5));
     return 0;
    }
    // Output: 16`
    
  • Słowo kluczowe return nie może być używane w makrach do zwracania wartości, jak w przypadku funkcji.

  • Funkcje Inline mogą być przeciążone

  • Tokeny przekazywane do makr mogą być łączone za pomocą operatora ## zwanego operatorem wklejania tokenów .

  • Makra są zwykle używane do ponownego użycia kodu, gdzie jako funkcje wbudowane są używane w celu wyeliminowania narzut czasu (nadmiar czasu) podczas wywołania funkcji (unikanie przeskoku do podprogramu).

 12
Author: fireblaze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-28 10:45:20

Aby dodać kolejną różnicę do już podanych: nie możesz przejść przez #define w debuggerze, ale możesz przejść przez funkcję wbudowaną.

 10
Author: RichieHindle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 13:39:07

Makra ignorują przestrzenie nazw. I to czyni ich złymi.

 8
Author: Kirill V. Lyadvinsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 13:34:01

Funkcje Inline są podobne do makr (ponieważ kod funkcji jest rozszerzany w punkcie wywołania podczas kompilacji), funkcje inline są przetwarzane przez kompilator, podczas gdy makra są rozszerzane przez preprocesor. W rezultacie istnieje kilka istotnych różnic:

  • Funkcje Inline są zgodne ze wszystkimi protokołami bezpieczeństwa typu wymuszonymi na normalnych funkcjach.
  • Funkcje Inline są określone przy użyciu tej samej składni, co każda inna funkcja, z wyjątkiem tego, że zawierają inline słowo kluczowe w deklaracji funkcji.
  • wyrażenia przekazane jako argumenty do funkcji inline są oceniane raz.
  • W niektórych przypadkach wyrażenia przekazane jako argumenty do makr mogą być oceniane więcej niż jeden raz. http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx

  • Makra są rozwijane podczas wstępnej kompilacji, nie można ich używać do debugowania, ale można używać funkcji wbudowanych.

-- dobrze. Artykuł : http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1

;

 3
Author: Ahmad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 14:11:48

Funkcja inline zachowuje semantykę wartości, podczas gdy makro preprocesora kopiuje składnię. Możesz uzyskać bardzo subtelne błędy z makrem preprocesora, jeśli użyjesz argumentu wiele razy - na przykład jeśli argument zawiera mutację w stylu "i++" posiadanie tego wykonania dwa razy jest sporym zaskoczeniem. Funkcja wbudowana nie będzie miała tego problemu.

 2
Author: Michael Donohue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 13:30:00

Inline functuion zachowuje się składniowo, podobnie jak normalna funkcja, zapewniając bezpieczeństwo typu i zakres dla zmiennych lokalnych funkcji oraz dostęp do elementów klasy, jeśli jest to metoda. Również podczas wywoływania metod inline należy stosować się do prywatnych / chronionych ograniczeń.

 1
Author: heeen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 13:29:14

W GCC (nie jestem pewien co do innych) deklarowanie funkcji inline jest tylko podpowiedzią dla kompilatora. Do kompilatora na koniec dnia pozostaje decyzja, czy zawiera Ciało funkcji, czy też nie, gdy jest wywoływana.

Różnica między funkcjami in-line a makrami preprocesora jest stosunkowo duża. Makra preprocesora są tylko zastępowaniem tekstu pod koniec dnia. Rezygnujesz z dużej zdolności kompilatora do sprawdzania typu sprawdzania na arguments I return type. Ocena argumentów jest znacznie inna (jeśli wyrażenia, które przekazujesz do funkcji mają skutki uboczne, będziesz miał bardzo przyjemny czas debugowania). Istnieją subtelne różnice co do tego, gdzie można używać funkcji i makr. Na przykład gdybym miał:

#define MACRO_FUNC(X) ...

Gdzie MACRO_FUNC definiuje ciało funkcji. Należy zachować szczególną ostrożność, aby działała poprawnie we wszystkich przypadkach, gdy może być użyta funkcja, na przykład źle napisane MACRO_FUNC powoduje błąd w

if(MACRO_FUNC(y)) {
 ...body
}

Normalna funkcja może być używana bez problemu.

 0
Author: Falaina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 13:37:46

Z punktu widzenia kodowania, funkcja inline jest jak funkcja. Tak więc różnice między funkcją inline i makro są takie same jak różnice między funkcją a Makro.

Z punktu widzenia kompilacji funkcja inline jest podobna do makra. Jest wstrzykiwany bezpośrednio do kodu, a nie wywoływany.

Ogólnie rzecz biorąc, powinieneś rozważyć funkcje inline jako funkcje regularne z drobną optymalizacją. I jak większość optymalizacji, to do kompilatora należy decyzja, czy faktycznie zależy mu na jego zastosowaniu. Często kompilator z radością ignoruje wszelkie próby programisty do wbudowania funkcji, z różnych powodów.

 0
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-16 13:42:13

Funkcje Inline będą zachowywać się jak wywołanie funkcji, jeśli istnieje w niej jakieś polecenie iteracyjne lub rekurencyjne, aby zapobiec powtarzaniu instrukcji. Jego bardzo pomocne, aby zapisać ogólną pamięć programu.

 0
Author: Arashdeep singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-17 21:53:19
#include<iostream>
using namespace std;
#define NUMBER 10 //macros are preprocessed while functions are not.
int number()
{ 
    return 10;
}
/*In macros, no type checking(incompatible operand, etc.) is done and thus use of micros can lead to errors/side-effects in some cases. 
However, this is not the case with functions.
Also, macros do not check for compilation error (if any). Consider:- */
#define CUBE(b) b*b*b
int cube(int a)
{
 return a*a*a;
}
int main()
{
 cout<<NUMBER<<endl<<number()<<endl;
 cout<<CUBE(1+3); //Unexpected output 10
 cout<<endl<<cube(1+3);// As expected 64
 return 0;
}

Makra są zazwyczaj szybsze niż funkcje, ponieważ nie wiążą się z rzeczywistym wywołaniem funkcji.

Niektóre wady makr: Nie ma sprawdzania typu.Trudne do debugowania, ponieważ powodują prostą wymianę.Makro nie ma przestrzeni nazw, więc makro w jednej sekcji kodu może wpływać na drugą sekcję. Makra mogą powodować działania niepożądane, jak pokazano w powyższym przykładzie CUBE ().

Makra to zwykle jedna linijka. Mogą jednak składać się z więcej niż jednej linii.Nie ma takich ograniczenia w funkcjach.

 -1
Author: AngryNerd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 22:25:03