Preprocesor C - tworzenie unikalnych nazw zmiennych

0

Mam sobie taki kod:

#define MERGE(a,b) a##b
#define DECL_INT_IMPL(ln) int MERGE(intVar, ln)
#define DECL_INT DECL_INT_IMPL(__LINE__)
int main(int, char **)
{
	DECL_INT ;
	DECL_INT = 100 ;
	DECL_INT ;
	DECL_INT_IMPL(__LINE__) ;
	
	return 0 ;
}

Po przejściu preprocesora wygląda to tak:

int main(int, char **)
{
 int intVar6 ;
 int intVar7 = 100 ;
 int intVar8 ;
 int intVar9 ;

 return 0 ;
}

Ale gdy chcę skrócić to do:

#define DECL_INT_IMPL(ln) int intVar##ln
#define DECL_INT DECL_INT_IMPL(__LINE__)
int main(int, char **)
{
	DECL_INT ; 
	DECL_INT = 100 ;
	DECL_INT ;
	DECL_INT_IMPL(__LINE__) ;
	
	return 0 ;
}

To LINE nie zostaje sparsowane:

int main(int, char **)
{
 int intVar__LINE__ ;
 int intVar__LINE__ = 100 ;
 int intVar__LINE__ ;
 int intVar__LINE__ ;

 return 0 ;
}

Czy ktoś jest w stanie wytłumaczyć czemu, albo podesłać link do dokumentacji?

0

nie wiem dlaczego tak się dzieje, ale zobacz co Clang wyrzuca:

c:\pp\myprogs\c>clang test2.c
test2.c:3:13: error: parameter name omitted
int main(int, char **)
            ^
test2.c:3:22: error: parameter name omitted
int main(int, char **)
                     ^
test2.c:6:9: error: redefinition of 'intVar__LINE__'
        DECL_INT = 100 ;
        ^
test2.c:2:18: note: expanded from:
#define DECL_INT DECL_INT_IMPL(__LINE__)
                 ^
test2.c:1:31: note: expanded from:
#define DECL_INT_IMPL(ln) int intVar##ln
                              ^
<scratch space>:3:1: note: expanded from:
intVar__LINE__
^
test2.c:5:9: note: previous definition is here
        DECL_INT ;
        ^
test2.c:2:18: note: expanded from:
#define DECL_INT DECL_INT_IMPL(__LINE__)
                 ^
test2.c:1:31: note: expanded from:
#define DECL_INT_IMPL(ln) int intVar##ln
                              ^
<scratch space>:2:1: note: expanded from:
intVar__LINE__
^
test2.c:7:9: error: redefinition of 'intVar__LINE__'
        DECL_INT ;
        ^
test2.c:2:18: note: expanded from:
#define DECL_INT DECL_INT_IMPL(__LINE__)
                 ^
test2.c:1:31: note: expanded from:
#define DECL_INT_IMPL(ln) int intVar##ln
                              ^
<scratch space>:3:1: note: expanded from:
intVar__LINE__
^
test2.c:5:9: note: previous definition is here
        DECL_INT ;
        ^
test2.c:2:18: note: expanded from:
#define DECL_INT DECL_INT_IMPL(__LINE__)
                 ^
test2.c:1:31: note: expanded from:
#define DECL_INT_IMPL(ln) int intVar##ln
                              ^
<scratch space>:2:1: note: expanded from:
intVar__LINE__
^
test2.c:8:9: error: redefinition of 'intVar__LINE__'
        DECL_INT_IMPL(__LINE__) ;
        ^
test2.c:1:31: note: expanded from:
#define DECL_INT_IMPL(ln) int intVar##ln
                              ^
<scratch space>:3:1: note: expanded from:
intVar__LINE__
^
test2.c:5:9: note: previous definition is here
        DECL_INT ;
        ^
test2.c:2:18: note: expanded from:
#define DECL_INT DECL_INT_IMPL(__LINE__)
                 ^
test2.c:1:31: note: expanded from:
#define DECL_INT_IMPL(ln) int intVar##ln
                              ^
<scratch space>:2:1: note: expanded from:
intVar__LINE__
^
5 errors generated.

a konkretnie w tym miejscu:

<scratch space>:3:1: note: expanded from:
intVar__LINE__

widać że to __LINE__ jest rozwiązywane nie w pliku, tylko jakimś „scratch space”, w którym jak widać LINE nie istnieje…

2

PS. wydaje mi się, że w tym miejscu

#define DECL_INT_IMPL(ln) int intVar##ln

powodujesz sklejenie intVar z tekstem __LINE__ zanim to LINE zostanie rozwiązane jako makro. Póżniej intVar__LINE__ jako całość nie jest już żadnym makrem.

0

Dzięki za rzeczową odpowiedź.

A co do tych 2 błędów:

c:\pp\myprogs\c>clang test2.c
test2.c:3:13: error: parameter name omitted
int main(int, char **)
            ^
test2.c:3:22: error: parameter name omitted
int main(int, char **)
                     ^

To kompilowałem g++, nie zwróciłem uwagi. W C powinny być nazwy parametrów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1