Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #142516 > unrolled thread

Question about #error

Started bygazelle@shell.xmission.com (Kenny McCormack)
First post2019-03-27 16:06 +0000
Last post2019-03-29 07:32 -0700
Articles 20 on this page of 35 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  Question about #error gazelle@shell.xmission.com (Kenny McCormack) - 2019-03-27 16:06 +0000
    Re: Question about #error Chad <cdalten@gmail.com> - 2019-03-27 10:21 -0700
    Re: Question about #error scott@slp53.sl.home (Scott Lurndal) - 2019-03-27 17:35 +0000
      Re: Question about #error nobody@example.org (Scott) - 2019-03-28 04:33 +0000
        Re: Question about #error Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-04-07 00:15 -0700
          Re: Question about #error gazelle@shell.xmission.com (Kenny McCormack) - 2019-04-07 10:22 +0000
            Re: Question about #error nobody@example.org (Scott) - 2019-04-07 17:10 +0000
    Re: Question about #error Bart <bc@freeuk.com> - 2019-03-27 17:52 +0000
    Re: Question about #error luser droog <luser.droog@gmail.com> - 2019-03-27 12:36 -0700
      Re: Question about #error luser droog <luser.droog@gmail.com> - 2019-03-27 12:47 -0700
    Re: Question about #error John Bode <jfbode1029@gmail.com> - 2019-03-27 14:28 -0700
      Re: Question about #error David Brown <david.brown@hesbynett.no> - 2019-03-27 22:38 +0100
    Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-03-28 13:59 -0700
      Re: Question about #error Keith Thompson <kst-u@mib.org> - 2019-03-28 14:28 -0700
        Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-03-29 07:09 -0700
          Re: Question about #error James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-03-29 08:05 -0700
            Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-03-29 12:08 -0700
              Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-03-29 12:15 -0700
              Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-03-29 12:53 -0700
            Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-03-30 14:40 -0700
              Re: Question about #error Keith Thompson <kst-u@mib.org> - 2019-03-30 15:19 -0700
                Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-03-30 16:17 -0700
                  Re: Question about #error scott@slp53.sl.home (Scott Lurndal) - 2019-03-31 19:12 +0000
                    Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-04-01 04:32 -0700
                Re: Question about #error David Brown <david.brown@hesbynett.no> - 2019-03-31 20:17 +0200
                  Re: Question about #error Richard Damon <Richard@Damon-Family.org> - 2019-03-31 15:09 -0400
                    Re: Question about #error David Brown <david.brown@hesbynett.no> - 2019-03-31 21:46 +0200
                  Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-04-01 04:36 -0700
              Re: Question about #error James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-04-02 17:47 -0700
                Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-04-03 05:31 -0700
                  Re: Question about #error James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-04-03 06:46 -0700
                    Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-04-03 07:44 -0700
                      Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-04-03 09:46 -0700
      Re: Question about #error scott@slp53.sl.home (Scott Lurndal) - 2019-03-28 21:29 +0000
      Re: Question about #error Thiago Adams <thiago.adams@gmail.com> - 2019-03-29 07:32 -0700

Page 1 of 2  [1] 2  Next page →


#142516 — Question about #error

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2019-03-27 16:06 +0000
SubjectQuestion about #error
Message-ID<q7g72f$59q$1@news.xmission.com>
(Using gcc on Linux)

I always assumed that #error would abort the compilation right then and
there, rather than try to continue and report other errors.  Since,
conceptually, pre-processing happens first before any "real" compilation,
you would think that if the pre-processor hits a #error directive, it would
abort there before any actual syntactual analysis was done.

However, I had a construct like this:

#if something == foo
int i;
#elif something == bar
double i;
#else
#error "It has to be either foo or bar"
#endif
/* Code that uses "i" */

When I compile it, and something is not either foo or bar, I get the #error
message displayed, then I get complaints about "i" not being defined.

As I say, this is not what I'd expect.

What is going on?


-- 
Faced with the choice between changing one's mind and proving that there is
no need to do so, almost everyone gets busy on the proof. 

    - John Kenneth Galbraith -

[toc] | [next] | [standalone]


#142518

FromChad <cdalten@gmail.com>
Date2019-03-27 10:21 -0700
Message-ID<037bbe67-0844-45f0-92ef-ece8fce56a2b@googlegroups.com>
In reply to#142516
On Wednesday, March 27, 2019 at 9:06:47 AM UTC-7, Kenny McCormack wrote:
> (Using gcc on Linux)
> 
> I always assumed that #error would abort the compilation right then and
> there, rather than try to continue and report other errors.  Since,
> conceptually, pre-processing happens first before any "real" compilation,
> you would think that if the pre-processor hits a #error directive, it would
> abort there before any actual syntactual analysis was done.
> 
> However, I had a construct like this:
> 
> #if something == foo
> int i;
> #elif something == bar
> double i;
> #else
> #error "It has to be either foo or bar"
> #endif
> /* Code that uses "i" */
> 
> When I compile it, and something is not either foo or bar, I get the #error
> message displayed, then I get complaints about "i" not being defined.
> 
> As I say, this is not what I'd expect.
> 
> What is going on?
> 
> 
> -- 

You first must ask yourself "Would Jesus approve of this?"

[toc] | [prev] | [next] | [standalone]


#142519

Fromscott@slp53.sl.home (Scott Lurndal)
Date2019-03-27 17:35 +0000
Message-ID<kvOmE.495298$YR5.287046@fx45.iad>
In reply to#142516
>On Wednesday, March 27, 2019 at 9:06:47 AM UTC-7, Kenny McCormack wrote:
>> (Using gcc on Linux)
>> 
>> I always assumed that #error would abort the compilation right then and
>> there, rather than try to continue and report other errors.  Since,
>> conceptually, pre-processing happens first before any "real" compilation,
>> you would think that if the pre-processor hits a #error directive, it would
>> abort there before any actual syntactual analysis was done.
>> 
>> However, I had a construct like this:
>> 
>> #if something == foo
>> int i;
>> #elif something == bar
>> double i;
>> #else
>> #error "It has to be either foo or bar"
>> #endif
>> /* Code that uses "i" */
>> 
>> When I compile it, and something is not either foo or bar, I get the #error
>> message displayed, then I get complaints about "i" not being defined.
>> 
>> As I say, this is not what I'd expect.
>> 
>> What is going on?


4 The implementation shall not successfully translate a preprocessing translation unit
  containing a #error preprocessing directive unless it is part of a group skipped by
  conditional inclusion.

1 A preprocessing directive of the form
     # error pp-tokensopt new-line
  causes the implementation to produce a diagnostic message that includes the specified
  sequence of preprocessing tokens.


That means the compilation need ultimately fail and that
a diagnostic be produced, but says nothing about further processing.

[toc] | [prev] | [next] | [standalone]


#142533

Fromnobody@example.org (Scott)
Date2019-03-28 04:33 +0000
Message-ID<5c9c4cbb.822065408@core>
In reply to#142519
On Wed, 27 Mar 2019 17:35:12 GMT, scott@slp53.sl.home (Scott Lurndal)
wrote:

>>On Wednesday, March 27, 2019 at 9:06:47 AM UTC-7, Kenny McCormack wrote:
>>> (Using gcc on Linux)
>>> 
>>> I always assumed that #error would abort the compilation right then and
>>> there, rather than try to continue and report other errors.  Since,
>
>4 The implementation shall not successfully translate a preprocessing translation unit
>  containing a #error preprocessing directive unless it is part of a group skipped by
>  conditional inclusion.
...
>That means the compilation need ultimately fail and that
>a diagnostic be produced, but says nothing about further processing.

That meshes with my experience. An #error does cause the comiplation
to fail, but not necessarily right away. Not unlike many other
non-showstopping errors.

I like that because it gives you a bigger list of things to fix before
recompiling. I do not like that an #error can therefore get lost in
the noise of other errors, since #error is often an important message
from one programmer to another.

I wonder if there's a compiler flag to have it regard #error as an
immediate halting point. I don't wonder enough to look it up though.

[toc] | [prev] | [next] | [standalone]


#142884

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2019-04-07 00:15 -0700
Message-ID<86o95il20y.fsf@mailhub.linuxsc.com>
In reply to#142533
nobody@example.org (Scott) writes:

> On Wed, 27 Mar 2019 17:35:12 GMT, scott@slp53.sl.home (Scott Lurndal)
> wrote:
>
>>> On Wednesday, March 27, 2019 at 9:06:47 AM UTC-7, Kenny McCormack wrote:
>>>
>>>> (Using gcc on Linux)
>>>>
>>>> I always assumed that #error would abort the compilation right then and
>>>> there, rather than try to continue and report other errors.  Since,
>>
>> 4 The implementation shall not successfully translate a preprocessing translation unit
>>  containing a #error preprocessing directive unless it is part of a group skipped by
>>  conditional inclusion.
>
> ...
>
>> That means the compilation need ultimately fail and that
>> a diagnostic be produced, but says nothing about further processing.
>
> That meshes with my experience.  An #error does cause the comiplation
> to fail, but not necessarily right away.  Not unlike many other
> non-showstopping errors.
>
> I like that because it gives you a bigger list of things to fix before
> recompiling.  I do not like that an #error can therefore get lost in
> the noise of other errors, since #error is often an important message
> from one programmer to another.
>
> I wonder if there's a compiler flag to have it regard #error as an
> immediate halting point.  I don't wonder enough to look it up though.

I believe there is not, at least for gcc.  In practice
though I expect the following would have the desired
effect:

    #error ... your message here ...
    #include "no-such-file-so-stop-compiling-already.h"

[toc] | [prev] | [next] | [standalone]


#142885

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2019-04-07 10:22 +0000
Message-ID<q8cj1v$st6$2@news.xmission.com>
In reply to#142884
In article <86o95il20y.fsf@mailhub.linuxsc.com>,
Tim Rentsch  <tr.17687@z991.linuxsc.com> wrote:
...
>> I wonder if there's a compiler flag to have it regard #error as an
>> immediate halting point.  I don't wonder enough to look it up though.
>
>I believe there is not, at least for gcc.  In practice
>though I expect the following would have the desired
>effect:
>
>    #error ... your message here ...
>    #include "no-such-file-so-stop-compiling-already.h"
>

This is a good suggestion - and, really nice that this thread finally got
back on-topic after all the ranting and raving about other stuff that many
posters have engaged in.  I will try it out at some point.  Thanks.

-- 
"He is exactly as they taught in KGB school: an egoist, a liar, but talented - he
knows the mind of the wrestling-loving, under-educated, authoritarian-admiring
white male populous."
    - Malcolm Nance, p59. -

[toc] | [prev] | [next] | [standalone]


#142888

Fromnobody@example.org (Scott)
Date2019-04-07 17:10 +0000
Message-ID<5caa2e4f.1731781783@core>
In reply to#142885
On Sun, 7 Apr 2019 10:22:55 -0000 (UTC), gazelle@shell.xmission.com
(Kenny McCormack) wrote:

>In article <86o95il20y.fsf@mailhub.linuxsc.com>,
>Tim Rentsch  <tr.17687@z991.linuxsc.com> wrote:
>...
>>> I wonder if there's a compiler flag to have it regard #error as an
>>> immediate halting point.  I don't wonder enough to look it up though.
>>
>>I believe there is not, at least for gcc.  In practice
>>though I expect the following would have the desired
>>effect:
>>
>>    #error ... your message here ...
>>    #include "no-such-file-so-stop-compiling-already.h"
>>
>
>This is a good suggestion - and, really nice that this thread finally got
>back on-topic after all the ranting and raving about other stuff that many
>posters have engaged in.  I will try it out at some point.  Thanks.

That *is* a good hint. Clever.

With my luck, "no-such-file-so-stop-compiling-already.h" would
actually exist as some kind of dummy load for compression or
encryption experiments. The chances of it containing valid C are low,
though.

[toc] | [prev] | [next] | [standalone]


#142520

FromBart <bc@freeuk.com>
Date2019-03-27 17:52 +0000
Message-ID<FLOmE.329700$TX3.53827@fx17.am4>
In reply to#142516
On 27/03/2019 16:06, Kenny McCormack wrote:
> (Using gcc on Linux)
> 
> I always assumed that #error would abort the compilation right then and
> there, rather than try to continue and report other errors.  Since,
> conceptually, pre-processing happens first before any "real" compilation,
> you would think that if the pre-processor hits a #error directive, it would
> abort there before any actual syntactual analysis was done.
> 
> However, I had a construct like this:
> 
> #if something == foo
> int i;
> #elif something == bar
> double i;
> #else
> #error "It has to be either foo or bar"
> #endif
> /* Code that uses "i" */
> 
> When I compile it, and something is not either foo or bar, I get the #error
> message displayed, then I get complaints about "i" not being defined.
> 
> As I say, this is not what I'd expect.
> 
> What is going on?

gcc is what's going on. If I try this:

     #define something 123

     #if something == foo
         int i;
     #elif something == bar
         double i;
     #else
         #error "It has to be either foo or bar"
     #endif

     int main(void) {
         i;
     }

     #error "final"

('something' has to be defined otherwise it will match 'foo')

Then only these Windows compilers will abort at that first error:

     Pelles C
     DMC
     Tiny C
     MSVC
     bcc

The following, without throwing further options at them (which are 
anyway under the control of whoever invokes the compiler, not the person 
writing that #error), will continue processing, complaining about the 
'i;' and displaying that second '#error':

     gcc
     clang
     lccwin

[toc] | [prev] | [next] | [standalone]


#142524

Fromluser droog <luser.droog@gmail.com>
Date2019-03-27 12:36 -0700
Message-ID<bf90e8b5-6ff6-4502-8fc8-ab7ad58b7243@googlegroups.com>
In reply to#142516
On Wednesday, March 27, 2019 at 11:06:47 AM UTC-5, Kenny McCormack wrote:
> (Using gcc on Linux)
> 
> I always assumed that #error would abort the compilation right then and
> there, rather than try to continue and report other errors.  Since,
> conceptually, pre-processing happens first before any "real" compilation,
> you would think that if the pre-processor hits a #error directive, it would
> abort there before any actual syntactual analysis was done.
> 
> However, I had a construct like this:
> 
> #if something == foo
> int i;
> #elif something == bar
> double i;
> #else
> #error "It has to be either foo or bar"
> #endif
> /* Code that uses "i" */
> 
> When I compile it, and something is not either foo or bar, I get the #error
> message displayed, then I get complaints about "i" not being defined.
> 
> As I say, this is not what I'd expect.
> 
> What is going on?
> 

I'll hazard an explanation (subject to correction by others of course).
Object-like macros behave a little differently in an #if directive than
they do in the regular source text.

quoting n1256.pdf:
6.10p7: The preprocessing tokens within a preprocessing directive are not subject to macro
expansion unless otherwise stated.

6.10.1p1: [In t]he expression that controls conditional inclusion ... identifiers (including those lexically identical to
keywords) are interpreted as described below ...

And here's the sneaky bit:

6.10.1p4: ... After all replacements due to macro expansion and the defined unary
operator have been performed, all remaining identifiers (including those lexically
identical to keywords) are replaced with the pp-number 0, and then each preprocessing
token is converted into a token. ...

So, if the identifier is not the name of an object-like macro, it will be
replaced by 0. In the OP example, I think this applies to the identifiers
"foo" and "bar" unless they are macros which expand to a number.

[toc] | [prev] | [next] | [standalone]


#142525

Fromluser droog <luser.droog@gmail.com>
Date2019-03-27 12:47 -0700
Message-ID<2009f98a-a4e8-4c17-bc9f-c712f0244645@googlegroups.com>
In reply to#142524
On Wednesday, March 27, 2019 at 2:37:15 PM UTC-5, luser droog wrote:
> On Wednesday, March 27, 2019 at 11:06:47 AM UTC-5, Kenny McCormack wrote:
> > (Using gcc on Linux)
> > 
> > I always assumed that #error would abort the compilation right then and
> > there, rather than try to continue and report other errors.  Since,
> > conceptually, pre-processing happens first before any "real" compilation,
> > you would think that if the pre-processor hits a #error directive, it would
> > abort there before any actual syntactual analysis was done.
> > 
> > However, I had a construct like this:
> > 
> > #if something == foo
> > int i;
> > #elif something == bar
> > double i;
> > #else
> > #error "It has to be either foo or bar"
> > #endif
> > /* Code that uses "i" */
> > 
> > When I compile it, and something is not either foo or bar, I get the #error
> > message displayed, then I get complaints about "i" not being defined.
> > 
> > As I say, this is not what I'd expect.
> > 
> > What is going on?
> > 
> 

<snip>
Oops, I think I was answering the wrong question. Sorry for the noise/

[toc] | [prev] | [next] | [standalone]


#142528

FromJohn Bode <jfbode1029@gmail.com>
Date2019-03-27 14:28 -0700
Message-ID<59aa387d-6a39-45ca-aac1-3cbc4e3e7aa7@googlegroups.com>
In reply to#142516
On Wednesday, March 27, 2019 at 11:06:47 AM UTC-5, Kenny McCormack wrote:
> (Using gcc on Linux)
> 
> I always assumed that #error would abort the compilation right then and
> there, rather than try to continue and report other errors.  Since,
> conceptually, pre-processing happens first before any "real" compilation,
> you would think that if the pre-processor hits a #error directive, it would
> abort there before any actual syntactual analysis was done.
> 
> However, I had a construct like this:
> 
> #if something == foo
> int i;
> #elif something == bar
> double i;
> #else
> #error "It has to be either foo or bar"
> #endif
> /* Code that uses "i" */
> 
> When I compile it, and something is not either foo or bar, I get the #error
> message displayed, then I get complaints about "i" not being defined.
> 
> As I say, this is not what I'd expect.
> 
> What is going on?
> 

The only requirement is that a diagnostic be issued, and that translation *ultimately* 
fail.  There's no requirement that translation be halted immediately upon processing
an #error directive.  

I agree that's not the most intuitive interpretation.  

[toc] | [prev] | [next] | [standalone]


#142530

FromDavid Brown <david.brown@hesbynett.no>
Date2019-03-27 22:38 +0100
Message-ID<q7gqhe$v91$1@dont-email.me>
In reply to#142528
On 27/03/2019 22:28, John Bode wrote:
> On Wednesday, March 27, 2019 at 11:06:47 AM UTC-5, Kenny McCormack wrote:
>> (Using gcc on Linux)
>>
>> I always assumed that #error would abort the compilation right then and
>> there, rather than try to continue and report other errors.  Since,
>> conceptually, pre-processing happens first before any "real" compilation,
>> you would think that if the pre-processor hits a #error directive, it would
>> abort there before any actual syntactual analysis was done.
>>
>> However, I had a construct like this:
>>
>> #if something == foo
>> int i;
>> #elif something == bar
>> double i;
>> #else
>> #error "It has to be either foo or bar"
>> #endif
>> /* Code that uses "i" */
>>
>> When I compile it, and something is not either foo or bar, I get the #error
>> message displayed, then I get complaints about "i" not being defined.
>>
>> As I say, this is not what I'd expect.
>>
>> What is going on?
>>
> 
> The only requirement is that a diagnostic be issued, and that translation *ultimately*
> fail.  There's no requirement that translation be halted immediately upon processing
> an #error directive.
> 
> I agree that's not the most intuitive interpretation.
> 

Sometimes it is useful for a compiler to stop on the first error so that 
you find it quickly.  Sometimes it is useful to continue and give 
further error messages, so that you can fix multiple problems before 
re-compiling, or because later messages give you a clue about how best 
to fix the first one.  (If you are using an IDE, multiple error messages 
can be very useful - and it's quick and easy to see the first one.)

gcc gives you the choice - "-Wfatal-errors" makes it stop on the first 
error.  You also have "-fmax-errors=n" - setting this to 1 is like 
-Wfatal-errors.  Other compilers also often give a choice of behaviour 
here, but sometimes the default setting is the opposite of gcc's.

You pick your choice of defaults here as a compiler writer - there is no 
way you'll please everyone.

[toc] | [prev] | [next] | [standalone]


#142567

FromThiago Adams <thiago.adams@gmail.com>
Date2019-03-28 13:59 -0700
Message-ID<9183709e-58d4-47b5-9e2b-781600729a55@googlegroups.com>
In reply to#142516
On Wednesday, March 27, 2019 at 1:06:47 PM UTC-3, Kenny McCormack wrote:
> (Using gcc on Linux)
> 
> I always assumed that #error would abort the compilation right then and
> there, rather than try to continue and report other errors.  Since,
> conceptually, pre-processing happens first before any "real" compilation,
> you would think that if the pre-processor hits a #error directive, it would
> abort there before any actual syntactual analysis was done.

Compilers have a close relationship with the preprocessor,
but everyone (standard) wants to keep them separated.

The C standards describes the compilation in phases as if they
were separated steps. In case the compiler want to do it together
it has to mimic the behavior of phases.


What is funny is that compiler configuration like pragma pack
and many others are done using preprocessor.

How can a preprocessor be separated from compiler in this case?
(rhetorical question)


I have suggested in this group that the preprocessor should
be moved to the compiler phase and this would bring many
advantages. 

Compatibly in this case could be done using compiler flags 
and new code could take advantage of this modification.



[toc] | [prev] | [next] | [standalone]


#142569

FromKeith Thompson <kst-u@mib.org>
Date2019-03-28 14:28 -0700
Message-ID<lno95uadtm.fsf@kst-u.example.com>
In reply to#142567
Thiago Adams <thiago.adams@gmail.com> writes:
> On Wednesday, March 27, 2019 at 1:06:47 PM UTC-3, Kenny McCormack wrote:
>> (Using gcc on Linux)
>> 
>> I always assumed that #error would abort the compilation right then and
>> there, rather than try to continue and report other errors.  Since,
>> conceptually, pre-processing happens first before any "real" compilation,
>> you would think that if the pre-processor hits a #error directive, it would
>> abort there before any actual syntactual analysis was done.
>
> Compilers have a close relationship with the preprocessor,
> but everyone (standard) wants to keep them separated.
>
> The C standards describes the compilation in phases as if they
> were separated steps. In case the compiler want to do it together
> it has to mimic the behavior of phases.
>
>
> What is funny is that compiler configuration like pragma pack
> and many others are done using preprocessor.
>
> How can a preprocessor be separated from compiler in this case?
> (rhetorical question)

I'll answer it anyway.  If a #pragma has effects that can't happen
before translation phase 7 (syntax and semantic analysis and
translation), then some form of it has to appear in the output of the
earlier phases, and be recognized by the later phases.

It does seem odd that this kind of thing is done using preprocessor
syntax.  One possible reason is that it allows an implementation-defined
#pragma to affect preprocessing.

> I have suggested in this group that the preprocessor should
> be moved to the compiler phase and this would bring many
> advantages. 
>
> Compatibly in this case could be done using compiler flags 
> and new code could take advantage of this modification.

There's no requirement that the 8 translation phases have to be done
separately, only that a compiler must behave as if they were.  As long
as the end result is the same, the preprocessor can already be part of
the compiler.

If the phases were changed as you suggest, how would token-pasting work?

I'm not at all sure just what you're proposing, or how it differs from
the current definition.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#142586

FromThiago Adams <thiago.adams@gmail.com>
Date2019-03-29 07:09 -0700
Message-ID<167a6806-9b54-4b29-bd00-188e286d3c05@googlegroups.com>
In reply to#142569
On Thursday, March 28, 2019 at 6:28:46 PM UTC-3, Keith Thompson wrote:
> Thiago Adams  writes:
> > On Wednesday, March 27, 2019 at 1:06:47 PM UTC-3, Kenny McCormack wrote:
> >> (Using gcc on Linux)
> >> 
> >> I always assumed that #error would abort the compilation right then and
> >> there, rather than try to continue and report other errors.  Since,
> >> conceptually, pre-processing happens first before any "real" compilation,
> >> you would think that if the pre-processor hits a #error directive, it would
> >> abort there before any actual syntactual analysis was done.
> >
> > Compilers have a close relationship with the preprocessor,
> > but everyone (standard) wants to keep them separated.
> >
> > The C standards describes the compilation in phases as if they
> > were separated steps. In case the compiler want to do it together
> > it has to mimic the behavior of phases.
> >
> >
> > What is funny is that compiler configuration like pragma pack
> > and many others are done using preprocessor.
> >
> > How can a preprocessor be separated from compiler in this case?
> > (rhetorical question)
> 
> I'll answer it anyway.  If a #pragma has effects that can't happen
> before translation phase 7 (syntax and semantic analysis and
> translation), then some form of it has to appear in the output of the
> earlier phases, and be recognized by the later phases.
> 
> It does seem odd that this kind of thing is done using preprocessor
> syntax.  One possible reason is that it allows an implementation-defined
> #pragma to affect preprocessing.
> 
> > I have suggested in this group that the preprocessor should
> > be moved to the compiler phase and this would bring many
> > advantages. 
> >
> > Compatibly in this case could be done using compiler flags 
> > and new code could take advantage of this modification.
> 
> There's no requirement that the 8 translation phases have to be done
> separately, only that a compiler must behave as if they were.  As long
> as the end result is the same, the preprocessor can already be part of
> the compiler.
> 
> If the phases were changed as you suggest, how would token-pasting work?
> 
> I'm not at all sure just what you're proposing, or how it differs from
> the current definition.

Initially my suggestion was to add new rules for macro expansion 
and doing this we could have safer macros and better tools (like
the ones that make code refactoring).

However, having in mind that this could be an eternal discussion trying
to find what usages people want to accept or deny I think the best
way is to keep 100% compatibly for macro expansion and move on.

Token-pasting would work as it is today but in some way it needs
to have access to the compiler.

(In my C transpiler I am doing the token-pasting inside the tokenizer. 
When the tokenizer finds a identifier that is a macro it expands it 
first (internally) and the output tokens are after this internal 
expansion.)


So, I think the current definition doesn't need to change and we
may think in term of features first and then later to see if 
phases needs to be changed or not.

The feature I would like to have is to be able to ask in #if
block about the AST.

For instance:

#if sizeof(int) ... 
#if _IsDefined(MyFunction) ...
#if _IsDefined(MyVariable) ... 

Here _IsDefined  returns 1 if MyFunction or MyVariable are 
defined in the scope.

This usage is similar of C++ 'if constexpr' but it is much 
more general. 

Andrei Alexandrescu, had suggested "Static If I Had a Hammer" -
https://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Static-If-I-Had-a-Hammer

Andrei suggestion was not based on this pre-processor integration, 
but I think this is the best option. 

Since C++ 17 the preprocessor added __has_include 
https://en.cppreference.com/w/cpp/preprocessor/include

This is a way of asking something without using defined macros.

In the same way, today, if I want to ask if a function exists:

#if MYFUNCTION ....

I need to define the function 
void MyFunction(){}...

and define the macro
#define MYFUNCTION

Having this ability to ask directly if the function or variable exists
makes the live easier.



--

Microsoft compiler has __if_exists Statement:

https://docs.microsoft.com/en-us/cpp/cpp/if-exists-statement?view=vs-2017

---

It is interesting to notice that C# mimics some parts of C preprocessor.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#pre-processing-directives


"The term 'pre-processing directives' is used only for consistency with 
the C and C++ programming languages. In C#, there is no separate 
pre-processing step; pre-processing directives are processed as part 
of the lexical analysis phase."

The usage of #define in C# is much more restrict than C and the purpose 
is not macro expansion but compilation flags to be checked by #if.

C#- "Any #define and #undef directives in a source file must occur 
before the first token (Tokens) in the source file; otherwise a 
compile-time error occurs. In intuitive terms, #define and #undef
directives must precede any "real code" in the source file."

Here is the C# grammar
https://www.cs.vu.nl/grammarware/browsable/CSharp/grammar.html#1.10_Pre-processing_directives


[toc] | [prev] | [next] | [standalone]


#142592

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-03-29 08:05 -0700
Message-ID<554d9166-d9ca-4109-b40e-a79b6f14ac41@googlegroups.com>
In reply to#142586
On Friday, March 29, 2019 at 10:10:00 AM UTC-4, Thiago Adams wrote:
...
> Initially my suggestion was to add new rules for macro expansion 
> and doing this we could have safer macros and better tools (like
> the ones that make code refactoring).
> 
> However, having in mind that this could be an eternal discussion trying
> to find what usages people want to accept or deny I think the best
> way is to keep 100% compatibly for macro expansion and move on.
> 
> Token-pasting would work as it is today but in some way it needs
> to have access to the compiler.
> 
> (In my C transpiler I am doing the token-pasting inside the tokenizer. 
> When the tokenizer finds a identifier that is a macro it expands it 
> first (internally) and the output tokens are after this internal 
> expansion.)
> 
> 
> So, I think the current definition doesn't need to change and we
> may think in term of features first and then later to see if 
> phases needs to be changed or not.
> 
> The feature I would like to have is to be able to ask in #if
> block about the AST.
> 
> For instance:
> 
> #if sizeof(int) ... 
> #if _IsDefined(MyFunction) ...
> #if _IsDefined(MyVariable) ... 

#if expressions are evaluated during translation phase 4. Per the rules
currently in effect, sizeof(int) gets converted into 0(0) before
evaluation (6.10.1p4), resulting in a syntax error.
sizeof and int are recognized as keywords only during phase 7, and don't
have meanings attached to them until phase 8. I presume that _IsDefined
would be a new keyword, and MyFunction and MyVariable are identifiers,
so they would also be parsed out during translation phase 7, but not
given an actual meaning until translation phase 8.
These reprocessing directives determine which tokens get processed
during translation phases 5, 6, and 7. What should happen to those
tokens during those phases if you can't determine whether the condition
of a #if is true until translation phase 8?

You're going to have to radically modify the entire translation phase
concept to make anything like what you're talking about work.

> Since C++ 17 the preprocessor added __has_include 

That's easy - in both languages, #include is a preprocessing directive,
handled during phase 4, the same phase where #if conditions are
evaluated.

[toc] | [prev] | [next] | [standalone]


#142601

FromThiago Adams <thiago.adams@gmail.com>
Date2019-03-29 12:08 -0700
Message-ID<d81771e5-e7af-47e7-8477-fe25eaf0734e@googlegroups.com>
In reply to#142592
On Friday, March 29, 2019 at 12:05:53 PM UTC-3, James Kuyper wrote:
> On Friday, March 29, 2019 at 10:10:00 AM UTC-4, Thiago Adams wrote:
> ...
> > Initially my suggestion was to add new rules for macro expansion 
> > and doing this we could have safer macros and better tools (like
> > the ones that make code refactoring).
> > 
> > However, having in mind that this could be an eternal discussion trying
> > to find what usages people want to accept or deny I think the best
> > way is to keep 100% compatibly for macro expansion and move on.
> > 
> > Token-pasting would work as it is today but in some way it needs
> > to have access to the compiler.
> > 
> > (In my C transpiler I am doing the token-pasting inside the tokenizer. 
> > When the tokenizer finds a identifier that is a macro it expands it 
> > first (internally) and the output tokens are after this internal 
> > expansion.)
> > 
> > 
> > So, I think the current definition doesn't need to change and we
> > may think in term of features first and then later to see if 
> > phases needs to be changed or not.
> > 
> > The feature I would like to have is to be able to ask in #if
> > block about the AST.
> > 
> > For instance:
> > 
> > #if sizeof(int) ... 
> > #if _IsDefined(MyFunction) ...
> > #if _IsDefined(MyVariable) ... 
> 
> #if expressions are evaluated during translation phase 4. Per the rules
> currently in effect, sizeof(int) gets converted into 0(0) before
> evaluation (6.10.1p4), resulting in a syntax error.
> sizeof and int are recognized as keywords only during phase 7, and don't
> have meanings attached to them until phase 8. I presume that _IsDefined
> would be a new keyword, and MyFunction and MyVariable are identifiers,
> so they would also be parsed out during translation phase 7, but not
> given an actual meaning until translation phase 8.
> These reprocessing directives determine which tokens get processed
> during translation phases 5, 6, and 7. What should happen to those
> tokens during those phases if you can't determine whether the condition
> of a #if is true until translation phase 8?

Thanks for pointing out the phases. These phases description should 
change to allow this implementation.


To allow macro expansion in the same way it is today I think
the macro expansion must occur before #if evaluation. At the end
#if will be like 'static if'.

For instance,
#define X

#if defined(X) && sizeof(int) > 1
..
#endif

The later phases would see something like

_If (1 && sizeof(int) > 1) {
...
}

I added this _If. _If can be used inside macros. (Similar of _Pragma)

I realized this could replace the usage of _Generic that 
seams very complicated and not so useful today.

For instance:


#define cbrt(X) _Generic((X), \
              long double: cbrtl, \
                  default: cbrt,  \
                    float: cbrtf  \
)(X)

#define cbrt(X) \
  _If (__type_is((X), "long double") \
  {\
    cbrtl(X)\
  }\
  else (__type_is((X), "float") \
  {\
    cbrtf(X)\
  }\
  else\
  {\
    cbrt(X)\
  }

(Here { and } does not introduce scope)

Having the access to the compiler other functions like
_type_is can be added and everything makes sense. 
_is_integral , _is_struct etc..

At the end, #if is just a different and alternative way
to write the 'static if' of _If.

#error could be an alternative way of writing _Error("") 
in this case _Error also would be added and be something similar of _StaticAssert(false, ).

So we can imagine that we have new keywords inside the language.

_Include,   _If, _Ifdef , _Error, _Pragma (already there) and
we also have a alternative way to use these keywords
in a forma of '#single line' #include etc..

Token expansion happens before so maybe #define and #undef
don't have equivalent _Define and _Undef.

So, we can imagine the pre-processor having only one 
feature that is #define and #undef and macro expansion.

[toc] | [prev] | [next] | [standalone]


#142602

FromThiago Adams <thiago.adams@gmail.com>
Date2019-03-29 12:15 -0700
Message-ID<352c4379-e13d-47a8-9ada-44be4a9f255e@googlegroups.com>
In reply to#142601
On Friday, March 29, 2019 at 4:09:01 PM UTC-3, Thiago Adams wrote:
....

For instance, 
#define X 

#if defined(X) && sizeof(int) > 1 
.. 
#endif 

The later phases would see something like 

_If (1 && sizeof(int) > 1) { 
... 
} 

here there is one difference..like James pointed out
sizeof(int) would be expanded to 0(0) and I want to
expand it as normal macro. 
So defined(X) would be in incompatible mode and broke
existing code if we expand in normal mode.

One way to fix would be adding _Expr that would not 
in this mode (#if) evaluate the inner expression.

#if defined(X) && _Expr(sizeof(int) > 1)
.. 
#endif 

the later phases would see:

#if (1 && sizeof(int) > 1)
.. 
#endif 

[toc] | [prev] | [next] | [standalone]


#142603

FromThiago Adams <thiago.adams@gmail.com>
Date2019-03-29 12:53 -0700
Message-ID<3a458345-f779-4cad-8f29-549ec5d7ee22@googlegroups.com>
In reply to#142601
On Friday, March 29, 2019 at 4:09:01 PM UTC-3, Thiago Adams wrote:
[...]
> I realized this could replace the usage of _Generic that 
> seams very complicated and not so useful today.


We can see that both _Generic and _StaticAssert are features
that can be written with more basic facilities if we had
_If and _Error.

static_assert macro could be define as.

#define static_assert(x, message) \
  _If (!(x)) {\ _Error(message) }

We could have _Warning as well.

[toc] | [prev] | [next] | [standalone]


#142622

FromThiago Adams <thiago.adams@gmail.com>
Date2019-03-30 14:40 -0700
Message-ID<41ad852c-4691-43dc-ae82-616efd8b1d83@googlegroups.com>
In reply to#142592
On Friday, March 29, 2019 at 12:05:53 PM UTC-3, James Kuyper wrote:
...
> #if expressions are evaluated during translation phase 4. Per the rules
> currently in effect, sizeof(int) gets converted into 0(0) before
> evaluation (6.10.1p4), resulting in a syntax error.


Does anyone uses or find uses of identifiers not defined in 
#if expressions?

Like 
#if IDENTIFIER

and IDENTIFIER was never #defined.
The normal usage is 
#if defined(X) or 
#if X  
where X is defined as 1 or 0


I did a search in windows include directory for #if identifier
and I didn't find any usage where identifier was not defined.

I think this behavior could be deprecated and generate warning
or error.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web