Thread View: pl.comp.lang.c
16 messages
16 total messages
Started by M.M.
Thu, 03 Oct 2019 20:19
Błąd preprocesora czy czegoś nie rozumiem?
Author: M.M.
Date: Thu, 03 Oct 2019 20:19
Date: Thu, 03 Oct 2019 20:19
28 lines
1745 bytes
1745 bytes
Witam
Jest sobie poniższy program i działa:
#define TEST1( __x__ ) int __x__ = __LINE__
#define TEST2( __x__ ) int __x__ ## __LINE__ = 0
int main(int argc, char *argv[]) {
TEST1( x );
printf( "%d\n" , x );
// TEST2( y );
// TEST2( y );
return 0;
}
Jednak jak odkomentuję dwie line:
// TEST2( y );
// TEST2( y );
to już mam błąd:
redeclaration of 'int y__LINE__'
TEST2( y );
^
Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
Pozdrawiam
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: PawelS pawel(at)wbcd(dot)pl
Date: Thu, 03 Oct 2019 21:36
Date: Thu, 03 Oct 2019 21:36
39 lines
2319 bytes
2319 bytes
M.M. pisze:
> Witam
>
> Jest sobie poniższy program i działa:
>
> #define TEST1( __x__ ) int __x__ = __LINE__
> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
>
> int main(int argc, char *argv[]) {
> TEST1( x );
> printf( "%d\n" , x );
> // TEST2( y );
> // TEST2( y );
> return 0;
> }
>
> Jednak jak odkomentuję dwie line:
> // TEST2( y );
> // TEST2( y );
>
> to już mam błąd:
>
> redeclaration of 'int y__LINE__'
> TEST2( y );
> ^
>
> Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
Powyższy błąd nie ma nic wspólnego z "rozwija makro".
Spróbuj sam się wczuć w rolę preprocesora i podstaw sobie makro.
Powyższy problematyczny zapis jak dla mnie (mogę się mylić)
po ... (nie wiem jak to nazwać) przy kompilacji może wyglądać tak:
> // TEST2( y );
> // TEST2( y );
> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
int __y__ ## __LINE__ = 0;
int __y__ ## __LINE__ = 0;
niech mnie ktoś poprawi, ale to wygląda trochę jak
podwójna deklaracja tej samej zmiennej,
albo już zbyt zmęczony jestem ...
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: M.M.
Date: Thu, 03 Oct 2019 22:20
Date: Thu, 03 Oct 2019 22:20
43 lines
3002 bytes
3002 bytes
On Thursday, October 3, 2019 at 11:36:18 PM UTC+2, PawelS pawel(at)wbcd(dot)pl wrote:
> M.M. pisze:
> > Witam
> >
> > Jest sobie poniższy program i działa:
> >
> > #define TEST1( __x__ ) int __x__ = __LINE__
> > #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
> >
> > int main(int argc, char *argv[]) {
> > TEST1( x );
> > printf( "%d\n" , x );
> > // TEST2( y );
> > // TEST2( y );
> > return 0;
> > }
> >
> > Jednak jak odkomentuję dwie line:
> > // TEST2( y );
> > // TEST2( y );
> >
> > to już mam błąd:
> >
> > redeclaration of 'int y__LINE__'
> > TEST2( y );
> > ^
> >
> > Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
> Powyższy błąd nie ma nic wspólnego z "rozwija makro".
> Spróbuj sam się wczuć w rolę preprocesora i podstaw sobie makro.
> Powyższy problematyczny zapis jak dla mnie (mogę się mylić)
> po ... (nie wiem jak to nazwać) przy kompilacji może wyglądać tak:
> > // TEST2( y );
> > // TEST2( y );
> > #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
> int __y__ ## __LINE__ = 0;
> int __y__ ## __LINE__ = 0;
> niech mnie ktoś poprawi, ale to wygląda trochę jak
> podwójna deklaracja tej samej zmiennej,
> albo już zbyt zmęczony jestem ...
Ok, ale dlaczego (zgodnie z oczekiwaniami) działa makro TEST1?
Pozdrawiam
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: Maciek Godek
Date: Thu, 03 Oct 2019 22:20
Date: Thu, 03 Oct 2019 22:20
36 lines
2310 bytes
2310 bytes
W dniu czwartek, 3 października 2019 22:19:36 UTC+2 użytkownik M.M. napisał:
> Witam
>
> Jest sobie poniższy program i działa:
>
> #define TEST1( __x__ ) int __x__ = __LINE__
> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
>
> int main(int argc, char *argv[]) {
> TEST1( x );
> printf( "%d\n" , x );
> // TEST2( y );
> // TEST2( y );
> return 0;
> }
>
> Jednak jak odkomentuję dwie line:
> // TEST2( y );
> // TEST2( y );
>
> to już mam błąd:
>
> redeclaration of 'int y__LINE__'
> TEST2( y );
> ^
>
> Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
>
> Pozdrawiam
Zdaje się, że kolejność, w jakiej preprocesor rozwija argumenty, jest niezdefiniowana w standardzie, i zależy od implementacji.
Możesz spróbować taki trick:
#define _TEST2_(x, line) int x##line = 0
#define TEST2(x) _TEST2_(x, __LINE__)
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: Maciek Godek
Date: Thu, 03 Oct 2019 22:29
Date: Thu, 03 Oct 2019 22:29
43 lines
2873 bytes
2873 bytes
W dniu piątek, 4 października 2019 00:20:56 UTC+2 użytkownik Maciek Godek napisał:
> W dniu czwartek, 3 października 2019 22:19:36 UTC+2 użytkownik M.M. napisał:
> > Witam
> >
> > Jest sobie poniższy program i działa:
> >
> > #define TEST1( __x__ ) int __x__ = __LINE__
> > #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
> >
> > int main(int argc, char *argv[]) {
> > TEST1( x );
> > printf( "%d\n" , x );
> > // TEST2( y );
> > // TEST2( y );
> > return 0;
> > }
> >
> > Jednak jak odkomentuję dwie line:
> > // TEST2( y );
> > // TEST2( y );
> >
> > to już mam błąd:
> >
> > redeclaration of 'int y__LINE__'
> > TEST2( y );
> > ^
> >
> > Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
> >
> > Pozdrawiam
>
> Zdaje się, że kolejność, w jakiej preprocesor rozwija argumenty, jest niezdefiniowana w standardzie, i zależy od implementacji.
>
> Możesz spróbować taki trick:
>
> #define _TEST2_(x, line) int x##line = 0
> #define TEST2(x) _TEST2_(x, __LINE__)
a gdyby nie działało, spróbuj wprowadzić jeszcze jeden dodatkowy stopień zapośredniczenia, tj.
#define __TEST2__(x,line) int x##line = 0
#define _TEST2_(x,line) __TEST2__(x,line)
#define TEST2(x) _TEST2_(x,__LINE__)
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: M.M.
Date: Thu, 03 Oct 2019 22:40
Date: Thu, 03 Oct 2019 22:40
65 lines
3406 bytes
3406 bytes
On Friday, October 4, 2019 at 12:29:57 AM UTC+2, Maciek Godek wrote:
> W dniu piątek, 4 października 2019 00:20:56 UTC+2 użytkownik Maciek Godek napisał:
> > W dniu czwartek, 3 października 2019 22:19:36 UTC+2 użytkownik M.M. napisał:
> > > Witam
> > >
> > > Jest sobie poniższy program i działa:
> > >
> > > #define TEST1( __x__ ) int __x__ = __LINE__
> > > #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
> > >
> > > int main(int argc, char *argv[]) {
> > > TEST1( x );
> > > printf( "%d\n" , x );
> > > // TEST2( y );
> > > // TEST2( y );
> > > return 0;
> > > }
> > >
> > > Jednak jak odkomentuję dwie line:
> > > // TEST2( y );
> > > // TEST2( y );
> > >
> > > to już mam błąd:
> > >
> > > redeclaration of 'int y__LINE__'
> > > TEST2( y );
> > > ^
> > >
> > > Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
> > >
> > > Pozdrawiam
> >
> > Zdaje się, że kolejność, w jakiej preprocesor rozwija argumenty, jest niezdefiniowana w standardzie, i zależy od implementacji.
> >
> > Możesz spróbować taki trick:
> >
> > #define _TEST2_(x, line) int x##line = 0
> > #define TEST2(x) _TEST2_(x, __LINE__)
>
> a gdyby nie działało, spróbuj wprowadzić jeszcze jeden dodatkowy stopień zapośredniczenia, tj.
>
> #define __TEST2__(x,line) int x##line = 0
> #define _TEST2_(x,line) __TEST2__(x,line)
> #define TEST2(x) _TEST2_(x,__LINE__)
Spróbowałęm tego najpierw, ten sam efekt:
#define TEST1( __x__ ) int __x__ = __LINE__
#define TEST2_( __x__ , __l__ ) int __x__ ## __l__ = 0
#define TEST2( __x__ ) TEST2_(__x__ , __LINE__)
int main(int argc, char *argv[]) {
TEST1( x );
printf( "%d\n" , x );
TEST2( y );
TEST2( y );
return 0;
}
test_01.cpp:17: błąd: redeclaration of 'int y__LINE__'
TEST2( y );
^
Pozdrawiam
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: Maciek Godek
Date: Thu, 03 Oct 2019 23:16
Date: Thu, 03 Oct 2019 23:16
80 lines
6700 bytes
6700 bytes
W dniu piątek, 4 października 2019 00:40:22 UTC+2 użytkownik M.M. napisał:
> On Friday, October 4, 2019 at 12:29:57 AM UTC+2, Maciek Godek wrote:
> > W dniu piątek, 4 października 2019 00:20:56 UTC+2 użytkownik Maciek Godek napisał:
> > > W dniu czwartek, 3 października 2019 22:19:36 UTC+2 użytkownik M.M. napisał:
> > > > Witam
> > > >
> > > > Jest sobie poniższy program i działa:
> > > >
> > > > #define TEST1( __x__ ) int __x__ = __LINE__
> > > > #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
> > > >
> > > > int main(int argc, char *argv[]) {
> > > > TEST1( x );
> > > > printf( "%d\n" , x );
> > > > // TEST2( y );
> > > > // TEST2( y );
> > > > return 0;
> > > > }
> > > >
> > > > Jednak jak odkomentuję dwie line:
> > > > // TEST2( y );
> > > > // TEST2( y );
> > > >
> > > > to już mam błąd:
> > > >
> > > > redeclaration of 'int y__LINE__'
> > > > TEST2( y );
> > > > ^
> > > >
> > > > Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
> > > >
> > > > Pozdrawiam
> > >
> > > Zdaje się, że kolejność, w jakiej preprocesor rozwija argumenty, jest niezdefiniowana w standardzie, i zależy od implementacji.
> > >
> > > Możesz spróbować taki trick:
> > >
> > > #define _TEST2_(x, line) int x##line = 0
> > > #define TEST2(x) _TEST2_(x, __LINE__)
> >
> > a gdyby nie działało, spróbuj wprowadzić jeszcze jeden dodatkowy stopień zapośredniczenia, tj.
> >
> > #define __TEST2__(x,line) int x##line = 0
> > #define _TEST2_(x,line) __TEST2__(x,line)
> > #define TEST2(x) _TEST2_(x,__LINE__)
>
> Spróbowałęm tego najpierw, ten sam efekt:
Tutaj masz tylko jednostopniową ekspansję.
> #define TEST1( __x__ ) int __x__ = __LINE__
> #define TEST2_( __x__ , __l__ ) int __x__ ## __l__ = 0
> #define TEST2( __x__ ) TEST2_(__x__ , __LINE__)
>
> int main(int argc, char *argv[]) {
> TEST1( x );
> printf( "%d\n" , x );
> TEST2( y );
> TEST2( y );
> return 0;
> }
>
> test_01.cpp:17: błąd: redeclaration of 'int y__LINE__'
> TEST2( y );
> ^
>
> Pozdrawiam
No ja u siebie sprawdziłem:
x.c:
#define __TEST2__(x,line) int x##line = 0 #define _TEST2_(x,line) __TEST2__(x,line) #define TEST2(x) _TEST2_(x,__LINE__) TEST2(k);
$ cpp x.c
# 1 "x.c" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 32 "<command-line>" 2 # 1 "x.c" int k5 = 0; int k6 = 0;
Preprocesor mam z GCC 7.3.0
Czyli jak zrobisz dwustopniową ekspansje, to powinno działać (przyniajmniej w GCC)
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: Maciek Godek
Date: Thu, 03 Oct 2019 23:19
Date: Thu, 03 Oct 2019 23:19
93 lines
7283 bytes
7283 bytes
W dniu piątek, 4 października 2019 01:16:22 UTC+2 użytkownik Maciek Godek napisał:
> W dniu piątek, 4 października 2019 00:40:22 UTC+2 użytkownik M.M. napisał:
> > On Friday, October 4, 2019 at 12:29:57 AM UTC+2, Maciek Godek wrote:
> > > W dniu piątek, 4 października 2019 00:20:56 UTC+2 użytkownik Maciek Godek napisał:
> > > > W dniu czwartek, 3 października 2019 22:19:36 UTC+2 użytkownik M.M. napisał:
> > > > > Witam
> > > > >
> > > > > Jest sobie poniższy program i działa:
> > > > >
> > > > > #define TEST1( __x__ ) int __x__ = __LINE__
> > > > > #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
> > > > >
> > > > > int main(int argc, char *argv[]) {
> > > > > TEST1( x );
> > > > > printf( "%d\n" , x );
> > > > > // TEST2( y );
> > > > > // TEST2( y );
> > > > > return 0;
> > > > > }
> > > > >
> > > > > Jednak jak odkomentuję dwie line:
> > > > > // TEST2( y );
> > > > > // TEST2( y );
> > > > >
> > > > > to już mam błąd:
> > > > >
> > > > > redeclaration of 'int y__LINE__'
> > > > > TEST2( y );
> > > > > ^
> > > > >
> > > > > Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
> > > > >
> > > > > Pozdrawiam
> > > >
> > > > Zdaje się, że kolejność, w jakiej preprocesor rozwija argumenty, jest niezdefiniowana w standardzie, i zależy od implementacji.
> > > >
> > > > Możesz spróbować taki trick:
> > > >
> > > > #define _TEST2_(x, line) int x##line = 0
> > > > #define TEST2(x) _TEST2_(x, __LINE__)
> > >
> > > a gdyby nie działało, spróbuj wprowadzić jeszcze jeden dodatkowy stopień zapośredniczenia, tj.
> > >
> > > #define __TEST2__(x,line) int x##line = 0
> > > #define _TEST2_(x,line) __TEST2__(x,line)
> > > #define TEST2(x) _TEST2_(x,__LINE__)
> >
> > Spróbowałęm tego najpierw, ten sam efekt:
>
> Tutaj masz tylko jednostopniową ekspansję.
>
> > #define TEST1( __x__ ) int __x__ = __LINE__
> > #define TEST2_( __x__ , __l__ ) int __x__ ## __l__ = 0
> > #define TEST2( __x__ ) TEST2_(__x__ , __LINE__)
> >
> > int main(int argc, char *argv[]) {
> > TEST1( x );
> > printf( "%d\n" , x );
> > TEST2( y );
> > TEST2( y );
> > return 0;
> > }
> >
> > test_01.cpp:17: błąd: redeclaration of 'int y__LINE__'
> > TEST2( y );
> > ^
> >
> > Pozdrawiam
>
> No ja u siebie sprawdziłem:
>
> x.c:
> #define __TEST2__(x,line) int x##line = 0 #define _TEST2_(x,line) __TEST2__(x,line) #define TEST2(x) _TEST2_(x,__LINE__) TEST2(k);
>
> $ cpp x.c
>
> # 1 "x.c" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 32 "<command-line>" 2 # 1 "x.c" int k5 = 0; int k6 = 0;
>
> Preprocesor mam z GCC 7.3.0
>
> Czyli jak zrobisz dwustopniową ekspansje, to powinno działać (przyniajmniej w GCC)
Sory coś mi się posrało CRLF. W każdym razie jak zrobisz
#define TEST2__( __x__ , __l__ ) int __x__ ## __l__ = 0
#define TEST2_( __x__, __l__ ) TEST2__( __x__, __l__)
#define TEST2( __x__ ) TEST2_(__x__ , __LINE__)
to powinno być raczej git.
W każdym razie
/* u mnie działa */
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: M.M.
Date: Thu, 03 Oct 2019 23:32
Date: Thu, 03 Oct 2019 23:32
97 lines
7563 bytes
7563 bytes
On Friday, October 4, 2019 at 1:19:42 AM UTC+2, Maciek Godek wrote:
> W dniu piątek, 4 października 2019 01:16:22 UTC+2 użytkownik Maciek Godek napisał:
> > W dniu piątek, 4 października 2019 00:40:22 UTC+2 użytkownik M.M. napisał:
> > > On Friday, October 4, 2019 at 12:29:57 AM UTC+2, Maciek Godek wrote:
> > > > W dniu piątek, 4 października 2019 00:20:56 UTC+2 użytkownik Maciek Godek napisał:
> > > > > W dniu czwartek, 3 października 2019 22:19:36 UTC+2 użytkownik M.M. napisał:
> > > > > > Witam
> > > > > >
> > > > > > Jest sobie poniższy program i działa:
> > > > > >
> > > > > > #define TEST1( __x__ ) int __x__ = __LINE__
> > > > > > #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
> > > > > >
> > > > > > int main(int argc, char *argv[]) {
> > > > > > TEST1( x );
> > > > > > printf( "%d\n" , x );
> > > > > > // TEST2( y );
> > > > > > // TEST2( y );
> > > > > > return 0;
> > > > > > }
> > > > > >
> > > > > > Jednak jak odkomentuję dwie line:
> > > > > > // TEST2( y );
> > > > > > // TEST2( y );
> > > > > >
> > > > > > to już mam błąd:
> > > > > >
> > > > > > redeclaration of 'int y__LINE__'
> > > > > > TEST2( y );
> > > > > > ^
> > > > > >
> > > > > > Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
> > > > > >
> > > > > > Pozdrawiam
> > > > >
> > > > > Zdaje się, że kolejność, w jakiej preprocesor rozwija argumenty, jest niezdefiniowana w standardzie, i zależy od implementacji.
> > > > >
> > > > > Możesz spróbować taki trick:
> > > > >
> > > > > #define _TEST2_(x, line) int x##line = 0
> > > > > #define TEST2(x) _TEST2_(x, __LINE__)
> > > >
> > > > a gdyby nie działało, spróbuj wprowadzić jeszcze jeden dodatkowy stopień zapośredniczenia, tj.
> > > >
> > > > #define __TEST2__(x,line) int x##line = 0
> > > > #define _TEST2_(x,line) __TEST2__(x,line)
> > > > #define TEST2(x) _TEST2_(x,__LINE__)
> > >
> > > Spróbowałęm tego najpierw, ten sam efekt:
> >
> > Tutaj masz tylko jednostopniową ekspansję.
> >
> > > #define TEST1( __x__ ) int __x__ = __LINE__
> > > #define TEST2_( __x__ , __l__ ) int __x__ ## __l__ = 0
> > > #define TEST2( __x__ ) TEST2_(__x__ , __LINE__)
> > >
> > > int main(int argc, char *argv[]) {
> > > TEST1( x );
> > > printf( "%d\n" , x );
> > > TEST2( y );
> > > TEST2( y );
> > > return 0;
> > > }
> > >
> > > test_01.cpp:17: błąd: redeclaration of 'int y__LINE__'
> > > TEST2( y );
> > > ^
> > >
> > > Pozdrawiam
> >
> > No ja u siebie sprawdziłem:
> >
> > x.c:
> > #define __TEST2__(x,line) int x##line = 0 #define _TEST2_(x,line) __TEST2__(x,line) #define TEST2(x) _TEST2_(x,__LINE__) TEST2(k);
> >
> > $ cpp x.c
> >
> > # 1 "x.c" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 32 "<command-line>" 2 # 1 "x.c" int k5 = 0; int k6 = 0;
> >
> > Preprocesor mam z GCC 7.3.0
> >
> > Czyli jak zrobisz dwustopniową ekspansje, to powinno działać (przyniajmniej w GCC)
>
> Sory coś mi się posrało CRLF. W każdym razie jak zrobisz
>
> #define TEST2__( __x__ , __l__ ) int __x__ ## __l__ = 0
> #define TEST2_( __x__, __l__ ) TEST2__( __x__, __l__)
> #define TEST2( __x__ ) TEST2_(__x__ , __LINE__)
>
> to powinno być raczej git.
>
> W każdym razie
>
> /* u mnie działa */
Nie rozumiem, ale u mnie też działa. Dziękuję za pomoc.
Pozdrawiam
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: Tomasz Kaczanowski
Date: Fri, 04 Oct 2019 07:22
Date: Fri, 04 Oct 2019 07:22
14 lines
1416 bytes
1416 bytes
W dniu 2019-10-03 o 23:36, PawelS pawel(at)wbcd(dot)pl pisze: >> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0 > int __y__ ## __LINE__ = 0; > int __y__ ## __LINE__ = 0; > niech mnie ktoś poprawi, ale to wygląda trochę jak > podwójna deklaracja tej samej zmiennej, > albo już zbyt zmęczony jestem ... __LINE__ daje numer linii z miejsca gdzie jest wywołany, więc to będą 2 różne zmienne. -- http://kaczus.ppa.pl
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: Maciek Godek
Date: Fri, 04 Oct 2019 08:06
Date: Fri, 04 Oct 2019 08:06
79 lines
4295 bytes
4295 bytes
W dniu piątek, 4 października 2019 01:32:29 UTC+2 użytkownik M.M. napisał: > > Sory coś mi się posrało CRLF. W każdym razie jak zrobisz > > > > #define TEST2__( __x__ , __l__ ) int __x__ ## __l__ = 0 > > #define TEST2_( __x__, __l__ ) TEST2__( __x__, __l__) > > #define TEST2( __x__ ) TEST2_(__x__ , __LINE__) > > > > to powinno być raczej git. > > > > W każdym razie > > > > /* u mnie działa */ > > Nie rozumiem, ale u mnie też działa. Dziękuję za pomoc. > Pozdrawiam No to już wyjaśniam. Powinno być jasne, że jeżeli zdefiniujemy makro #define TEST3(__x__) int __x__ ## __LINE__ i napiszemy TEST3(x) to rozwinie Ci się to do int __x____LINE__ no bo jak inaczej mógłbyś dokleić identyfikator __LINE__ do swojej zmiennej w makrze? Jeżeli z kolei napiszemy #define TEST3__( __x__ , __l__ ) int __x__ ## __l__ #define TEST3( __x__ ) TEST3__(__x__, __LINE__) to teraz jak napiszesz TEST3(x) to zachowanie makra będzie zależeć od tego, czy preprocesor rozwija argumenty przed, czy po rozwinięciu makra (chodzi nam w szczególności o argument __LINE__) Jeżeli rozwija je po rozwinięciu makra (i na to wygląda), to efekt będzie taki sam, jak wcześniej, bo algorytm jest z grubsza taki: 1. rozwiń makro z definicji (===>) 2. rozwiń wszystkie użyte argumenty (--->) 3. jeżeli wyrażenie zawiera jeszcze jakieś symbole preprocesora, kontynuuj ekspansję Czyli mamy 1. TEST3(x) ===> TEST3_(x, __LINE__) 2. TEST3__(x, __LINE__) ---> TEST3__(x, __LINE__) (jedynym argumentem do TEST3 był x, który nie jest symbolem preprocesora. Ale gdyby był, to na tym etapie zostałby zamieniony) 3. TEST3__(x, __LINE__) ===> int x__LINE__ Za to jeśli sobie zdefiniujemy #define TEST2__( __x__ , __l__ ) int __x__ ## __l__ = 0 #define TEST2_( __x__, __l__ ) TEST2__( __x__, __l__) #define TEST2( __x__ ) TEST2_(__x__ , __LINE__) i napiszemy TEST2(x) to ekspansja przebiegnie następująco: 1. TEST2(x) ===> TEST2_(x, __LINE__) 2. TEST2_(x, __LINE__) ---> TEST2_(x, __LINE__) 3. TEST2_(x, __LINE__) ===> TEST2__(x, __LINE__) 4. TEST2__(x, __LINE__) ---> TEST2__(x, 7) (bo dokonaliśmy właśnie ekspansji argumentu) 5. TEST2__(x, 7) ===> int x7 6. żaden z argumentów nie występuje w rozwinięciu HTH
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: M.M.
Date: Fri, 04 Oct 2019 10:15
Date: Fri, 04 Oct 2019 10:15
18 lines
2157 bytes
2157 bytes
On Friday, October 4, 2019 at 9:22:14 AM UTC+2, Tomasz Kaczanowski wrote: > W dniu 2019-10-03 o 23:36, PawelS pawel(at)wbcd(dot)pl pisze: > > >> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0 > > int __y__ ## __LINE__ = 0; > > int __y__ ## __LINE__ = 0; > > niech mnie ktoś poprawi, ale to wygląda trochę jak > > podwójna deklaracja tej samej zmiennej, > > albo już zbyt zmęczony jestem ... > > __LINE__ daje numer linii z miejsca gdzie jest wywołany, więc to będą 2 > różne zmienne. Tak programista oczekuje, żeby były to dwie różnie zmienne, jednak kompilator dawał błąd jakby to była jedna zmienna (dwie zmienne o tej samej nazwie). Przy 'potrójnym wywołaniu' problem ustąpił. Pozdrawiam
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: Maciek Godek
Date: Fri, 04 Oct 2019 10:21
Date: Fri, 04 Oct 2019 10:21
22 lines
2714 bytes
2714 bytes
W dniu piątek, 4 października 2019 12:15:51 UTC+2 użytkownik M.M. napisał: > On Friday, October 4, 2019 at 9:22:14 AM UTC+2, Tomasz Kaczanowski wrote: > > W dniu 2019-10-03 o 23:36, PawelS pawel(at)wbcd(dot)pl pisze: > > > > >> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0 > > > int __y__ ## __LINE__ = 0; > > > int __y__ ## __LINE__ = 0; > > > niech mnie ktoś poprawi, ale to wygląda trochę jak > > > podwójna deklaracja tej samej zmiennej, > > > albo już zbyt zmęczony jestem ... > > > > __LINE__ daje numer linii z miejsca gdzie jest wywołany, więc to będą 2 > > różne zmienne. > > Tak programista oczekuje, żeby były to dwie różnie zmienne, jednak > kompilator dawał błąd jakby to była jedna zmienna (dwie zmienne o > tej samej nazwie). Przy 'potrójnym wywołaniu' problem ustąpił. Bo tak było. Tworzyłeś dwie instancje zmiennej o nazwie y__LINE__ w tym samym zasięgu. Przy zmaganiach z preprocesorem warto wywołać 'cpp' (czyli C PreProcessor), żeby zobaczyć, co trafia do kompilatora.
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: M.M.
Date: Fri, 04 Oct 2019 11:57
Date: Fri, 04 Oct 2019 11:57
27 lines
2929 bytes
2929 bytes
On Friday, October 4, 2019 at 12:21:39 PM UTC+2, Maciek Godek wrote: > W dniu piątek, 4 października 2019 12:15:51 UTC+2 użytkownik M.M. napisał: > > On Friday, October 4, 2019 at 9:22:14 AM UTC+2, Tomasz Kaczanowski wrote: > > > W dniu 2019-10-03 o 23:36, PawelS pawel(at)wbcd(dot)pl pisze: > > > > > > >> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0 > > > > int __y__ ## __LINE__ = 0; > > > > int __y__ ## __LINE__ = 0; > > > > niech mnie ktoś poprawi, ale to wygląda trochę jak > > > > podwójna deklaracja tej samej zmiennej, > > > > albo już zbyt zmęczony jestem ... > > > > > > __LINE__ daje numer linii z miejsca gdzie jest wywołany, więc to będą 2 > > > różne zmienne. > > > > Tak programista oczekuje, żeby były to dwie różnie zmienne, jednak > > kompilator dawał błąd jakby to była jedna zmienna (dwie zmienne o > > tej samej nazwie). Przy 'potrójnym wywołaniu' problem ustąpił. > > Bo tak było. Tworzyłeś dwie instancje zmiennej o nazwie y__LINE__ > w tym samym zasięgu. > > Przy zmaganiach z preprocesorem warto wywołać 'cpp' (czyli C PreProcessor), żeby zobaczyć, co trafia do kompilatora. Racja, warto. Pozdrawiam
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: Queequeg
Date: Fri, 04 Oct 2019 14:01
Date: Fri, 04 Oct 2019 14:01
12 lines
1326 bytes
1326 bytes
M.M. <mmarszik@gmail.com> wrote: > Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie? https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html "As with stringizing, the actual argument is not macro-expanded first." Btw, polecam gcc z opcją -E. Zobaczysz wtedy dokładnie, co się dzieje. -- https://www.youtube.com/watch?v=9lSzL1DqQn0
Re: Błąd preprocesora czy czegoś nie rozumiem?
Author: PawelS pawel(at)wbcd(dot)pl
Date: Wed, 09 Oct 2019 16:57
Date: Wed, 09 Oct 2019 16:57
51 lines
2731 bytes
2731 bytes
M.M. pisze:
> On Thursday, October 3, 2019 at 11:36:18 PM UTC+2, PawelS pawel(at)wbcd(dot)pl wrote:
>> M.M. pisze:
>>> Witam
>>>
>>> Jest sobie poniższy program i działa:
>>>
>>> #define TEST1( __x__ ) int __x__ = __LINE__
>>> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
>>>
>>> int main(int argc, char *argv[]) {
>>> TEST1( x );
>>> printf( "%d\n" , x );
>>> // TEST2( y );
>>> // TEST2( y );
>>> return 0;
>>> }
>>>
>>> Jednak jak odkomentuję dwie line:
>>> // TEST2( y );
>>> // TEST2( y );
>>>
>>> to już mam błąd:
>>>
>>> redeclaration of 'int y__LINE__'
>>> TEST2( y );
>>> ^
>>>
>>> Od czego zależy kiedy rozwija makro __LINE__ a kiedy nie?
>> Powyższy błąd nie ma nic wspólnego z "rozwija makro".
>> Spróbuj sam się wczuć w rolę preprocesora i podstaw sobie makro.
>> Powyższy problematyczny zapis jak dla mnie (mogę się mylić)
>> po ... (nie wiem jak to nazwać) przy kompilacji może wyglądać tak:
>>> // TEST2( y );
>>> // TEST2( y );
>>> #define TEST2( __x__ ) int __x__ ## __LINE__ = 0
>> int __y__ ## __LINE__ = 0;
>> int __y__ ## __LINE__ = 0;
>> niech mnie ktoś poprawi, ale to wygląda trochę jak
>> podwójna deklaracja tej samej zmiennej,
>> albo już zbyt zmęczony jestem ...
>
> Ok, ale dlaczego (zgodnie z oczekiwaniami) działa makro TEST1?
Makro TEST1 tylko dlatego, że występuje w kodzie tylko 1 raz.
Sprawdzałeś ? Czy zadziała gdy będzie występować 2 razy ?
TEST1( x );
TEST1( x );
a.c:9: error: redefinition of ‘x’
a.c:8: error: previous definition of ‘x’ was here
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads