🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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?
#309935
Author: M.M.
Date: Thu, 03 Oct 2019 20:19
28 lines
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?
#309943
Author: PawelS pawel(at)wbcd(dot)pl
Date: Thu, 03 Oct 2019 21:36
39 lines
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?
#309944
Author: M.M.
Date: Thu, 03 Oct 2019 22:20
43 lines
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?
#309936
Author: Maciek Godek
Date: Thu, 03 Oct 2019 22:20
36 lines
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?
#309937
Author: Maciek Godek
Date: Thu, 03 Oct 2019 22:29
43 lines
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?
#309938
Author: M.M.
Date: Thu, 03 Oct 2019 22:40
65 lines
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?
#309939
Author: Maciek Godek
Date: Thu, 03 Oct 2019 23:16
80 lines
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?
#309940
Author: Maciek Godek
Date: Thu, 03 Oct 2019 23:19
93 lines
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?
#309942
Author: M.M.
Date: Thu, 03 Oct 2019 23:32
97 lines
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?
#309947
Author: Tomasz Kaczanowski
Date: Fri, 04 Oct 2019 07:22
14 lines
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?
#309941
Author: Maciek Godek
Date: Fri, 04 Oct 2019 08:06
79 lines
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?
#309950
Author: M.M.
Date: Fri, 04 Oct 2019 10:15
18 lines
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?
#309952
Author: Maciek Godek
Date: Fri, 04 Oct 2019 10:21
22 lines
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?
#309948
Author: M.M.
Date: Fri, 04 Oct 2019 11:57
27 lines
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?
#309949
Author: Queequeg
Date: Fri, 04 Oct 2019 14:01
12 lines
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?
#309945
Author: PawelS pawel(at)wbcd(dot)pl
Date: Wed, 09 Oct 2019 16:57
51 lines
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