Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #142516 > unrolled thread
| Started by | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| First post | 2019-03-27 16:06 +0000 |
| Last post | 2019-03-29 07:32 -0700 |
| Articles | 20 on this page of 35 — 13 participants |
Back to article view | Back to comp.lang.c
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 →
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2019-03-27 16:06 +0000 |
| Subject | Question 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]
| From | Chad <cdalten@gmail.com> |
|---|---|
| Date | 2019-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-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]
| From | nobody@example.org (Scott) |
|---|---|
| Date | 2019-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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2019-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]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2019-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]
| From | nobody@example.org (Scott) |
|---|---|
| Date | 2019-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]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2019-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2019-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]
| From | John Bode <jfbode1029@gmail.com> |
|---|---|
| Date | 2019-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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