🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #309939

Re: Błąd preprocesora czy czegoś nie rozumiem?

#309939
From: 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)
Technical Details
Message-ID: <b3fd150a-5c5e-43e5-b2dd-fd6aa2e473c5@googlegroups.com>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!feeder.erje.net!2.eu.feeder.erje.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!o24no4102589qtl.0!news-out.google.com!q23ni510qtl.1!nntp.google.com!o24no4102583qtl.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
References: <780a7f39-337b-4b6b-810f-7c4151e10f74@googlegroups.com> <f1c8f951-ad5b-4fca-8e58-2fb7a4850aaa@googlegroups.com> <1abb73f5-4326-419c-a08d-499fbef10226@googlegroups.com> <ed39a49f-5fa2-4573-a688-08b160d397d4@googlegroups.com>

Show Full Headers
Complete Article Headers
X-Received: by 2002:ac8:4612:: with SMTP id p18mr12498874qtn.94.1570144581165;        Thu, 03 Oct 2019 16:16:21 -0700 (PDT)
X-Received: by 2002:a25:aac3:: with SMTP id t61mr88999ybi.201.1570144580904; Thu, 03 Oct 2019 16:16:20 -0700 (PDT)
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!feeder.erje.net!2.eu.feeder.erje.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!o24no4102589qtl.0!news-out.google.com!q23ni510qtl.1!nntp.google.com!o24no4102583qtl.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
Newsgroups: pl.comp.lang.c
Date: Thu, 3 Oct 2019 16:16:20 -0700 (PDT)
In-Reply-To: <ed39a49f-5fa2-4573-a688-08b160d397d4@googlegroups.com>
Complaints-To: groups-abuse@google.com
Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=83.25.250.157; posting-account=f7iIKQoAAAAkDKpUafc-4IXhmRAzdB5r
NNTP-Posting-Host: 83.25.250.157
References: <780a7f39-337b-4b6b-810f-7c4151e10f74@googlegroups.com> <f1c8f951-ad5b-4fca-8e58-2fb7a4850aaa@googlegroups.com> <1abb73f5-4326-419c-a08d-499fbef10226@googlegroups.com> <ed39a49f-5fa2-4573-a688-08b160d397d4@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <b3fd150a-5c5e-43e5-b2dd-fd6aa2e473c5@googlegroups.com>
Subject: Re: Błąd preprocesora czy
 czegoś nie rozumiem?
From: Maciek Godek <godek.maciek@gmail.com>
Injection-Date: Thu, 03 Oct 2019 23:16:21 +0000
Lines: 122
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit