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 15 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 2 of 2 — ← Prev page 1 [2]


#142623

FromKeith Thompson <kst-u@mib.org>
Date2019-03-30 15:19 -0700
Message-ID<lnd0m89f96.fsf@kst-u.example.com>
In reply to#142622
Thiago Adams <thiago.adams@gmail.com> writes:
> 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.

The meaning of

#if UNDEFINED_IDENTIFIER

is currently well defined.  Treating it as a fatal error could easily
break existing code.  (A Windows include directory is not likely to be a
representative sample.)

What would be the advantage of deprecating it?

-- 
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]


#142625

FromThiago Adams <thiago.adams@gmail.com>
Date2019-03-30 16:17 -0700
Message-ID<2a8c027b-f6f4-409a-9fa0-5ba634f177c8@googlegroups.com>
In reply to#142623
On Saturday, March 30, 2019 at 7:19:59 PM UTC-3, Keith Thompson wrote:
> Thiago Adams  writes:
> > 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.
> 
> The meaning of
> 
> #if UNDEFINED_IDENTIFIER
> 
> is currently well defined.  Treating it as a fatal error could easily
> break existing code.  (A Windows include directory is not likely to be a
> representative sample.)
> 
> What would be the advantage of deprecating it?

The motivation was to save my suggestion of using 
#if as an alternative syntax for 'static if' [1]
as an extension of the current #if in a way
that programmers feels natural.

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

instead of sizeof(int) going to 0(0) that is the 
current behavior, making it an error. Doing this
the meaning could be changed in the future like
adding my suggestion.

If this is not possible, I would need something
like

#if defined(X) && _Expression(sizeof(int))

but then, the syntax would not feel natural 
anymore.

if other syntax was added, let's say , #ifexpr then
I also think my specific suggestion of #if stops making
sense and the syntax could be only static if, as it was 
proposed.

I can see other advantages of making the preprocessor
more integrated with the compiler but I am selecting uses 
cases to back my suggestion.


We can see that #error and _StaticAssert are also two 
manifestation of the same desire of testing something
and depending on the result emit an error.

_Generic is also a manifestation of desire of selection by
testing something and then selecting tokens like #if.

#pragma and _Pragma are also manifestation of the desire of 
integration between preprocessor and compiler.


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


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


#142646

Fromscott@slp53.sl.home (Scott Lurndal)
Date2019-03-31 19:12 +0000
Message-ID<Pi8oE.196652$j34.151452@fx14.iad>
In reply to#142625
Thiago Adams <thiago.adams@gmail.com> writes:
>On Saturday, March 30, 2019 at 7:19:59 PM UTC-3, Keith Thompson wrote:
>> Thiago Adams  writes:
>> > 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.
>> >
>> >
>
>> 
>> The meaning of
>> 
>> #if UNDEFINED_IDENTIFIER
>> 
>> is currently well defined.  Treating it as a fatal error could easily
>> break existing code.  (A Windows include directory is not likely to be a
>> representative sample.)
>> 
>> What would be the advantage of deprecating it?
>
>The motivation was to save my suggestion of using 
>#if as an alternative syntax for 'static if' [1]
>as an extension of the current #if in a way
>that programmers feels natural.
>
>#if defined(X) && sizeof(int) > 1
>..

Have your preprocessor automatically define __BUILTIN_SIZEOF_INT,
__BUILTIN_SIZEOF_LONG, &c. matching the characteristics of the
target platform.

#if defined(X) && __BUILTIN_SIZEOF_INT != __BUILTIN_SIZEOF_LONG
 ...
#endif

Fits more naturally into the current pre-processor paradigm, imo.

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


#142684

FromThiago Adams <thiago.adams@gmail.com>
Date2019-04-01 04:32 -0700
Message-ID<a8e7d8d1-450d-4931-9c32-7be776574ff1@googlegroups.com>
In reply to#142646
On Sunday, March 31, 2019 at 4:12:55 PM UTC-3, Scott Lurndal wrote:
[...]
> Have your preprocessor automatically define __BUILTIN_SIZEOF_INT,
> __BUILTIN_SIZEOF_LONG, &c. matching the characteristics of the
> target platform.

The objective was to increase the integration between pre-processor
and compiler, removing the idea they are independent and doing this
opening new possibilities. I was suggesting the 
implementation of 'static if' (see references) as normal #if and
with an extra _If to be used inside macros just like #pragma and
_Pragma.

So the sizeof(int) is not the main point. The other usage is to 
inquire the existence of compiler symbols. VC++ already has an
exclusive feature for this that if __if_exists.

I have a practical use of __if_exists in my code.
Basically I add switch cases if the corespondent function
that handles that case exists.

Sample:

__if_exists (T::OnPaint)
        {
            case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hdc = BeginPaint(hWnd, &ps);
                pDoc->OnPaint(hdc);
                EndPaint(hWnd, &ps);
            }
            break;
        }

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


#142643

FromDavid Brown <david.brown@hesbynett.no>
Date2019-03-31 20:17 +0200
Message-ID<q7r07m$63s$1@dont-email.me>
In reply to#142623
On 30/03/2019 23:19, Keith Thompson wrote:
> Thiago Adams <thiago.adams@gmail.com> writes:
>> 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.
> 
> The meaning of
> 
> #if UNDEFINED_IDENTIFIER
> 
> is currently well defined.  Treating it as a fatal error could easily
> break existing code.  (A Windows include directory is not likely to be a
> representative sample.)
> 
> What would be the advantage of deprecating it?
> 

I think something like this would be extremely difficult to deprecate in 
the language, given how often it is used (it is, as you say, perfectly 
good coding).  (gcc "-Wundef" gives this behaviour, for those that want 
it - such as me, if I can get away with it.)

Personally, I much prefer to write:

#ifdef IDENTIFIER

or

#if defined(IDENTIFIER)

if it is possible for IDENTIFIER not to be defined - precisely because 
it makes it clear to the reader that the IDENTIFIER might not be 
defined.  And for the most part (where it is practically), I prefer to 
write:

#if FEATURE_ENABLED
...
#endif

with a configuration file saying:

#define FEATURE_ENABLED 1

or

#define FEATURE_ENABLED 0

This makes it a lot easier to find where this identifier is defined - 
where the configuration is done.  It is easy to search for the file and 
line that says this feature is not enabled, but very difficult to search 
for where it is just left undefined.


But even though I like to write my own code this way, it's an entirely 
different matter to say I think other people should code the way /I/ want.

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


#142645

FromRichard Damon <Richard@Damon-Family.org>
Date2019-03-31 15:09 -0400
Message-ID<yf8oE.311240$%45.47323@fx39.iad>
In reply to#142643
On 3/31/19 2:17 PM, David Brown wrote:
> On 30/03/2019 23:19, Keith Thompson wrote:
>> Thiago Adams <thiago.adams@gmail.com> writes:
>>> 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.
>>
>> The meaning of
>>
>> #if UNDEFINED_IDENTIFIER
>>
>> is currently well defined.  Treating it as a fatal error could easily
>> break existing code.  (A Windows include directory is not likely to be a
>> representative sample.)
>>
>> What would be the advantage of deprecating it?
>>
> 
> I think something like this would be extremely difficult to deprecate in
> the language, given how often it is used (it is, as you say, perfectly
> good coding).  (gcc "-Wundef" gives this behaviour, for those that want
> it - such as me, if I can get away with it.)
> 
> Personally, I much prefer to write:
> 
> #ifdef IDENTIFIER
> 
> or
> 
> #if defined(IDENTIFIER)
> 
> if it is possible for IDENTIFIER not to be defined - precisely because
> it makes it clear to the reader that the IDENTIFIER might not be
> defined.  And for the most part (where it is practically), I prefer to
> write:
> 
> #if FEATURE_ENABLED
> ...
> #endif
> 
> with a configuration file saying:
> 
> #define FEATURE_ENABLED 1
> 
> or
> 
> #define FEATURE_ENABLED 0
> 
> This makes it a lot easier to find where this identifier is defined -
> where the configuration is done.  It is easy to search for the file and
> line that says this feature is not enabled, but very difficult to search
> for where it is just left undefined.
> 
> 
> But even though I like to write my own code this way, it's an entirely
> different matter to say I think other people should code the way /I/ want.

I too prefer to use #if FEATURE instead of #ifdef FEATURE, as that
allows the configuration file to list all the options with
#define FEATURE 1 or
#define FEATURE 0

but, due to the current rules, if the configuration file doesn't have
any definition, then you get a default of not using the feature.

It is also possible to add sequences like

#ifndef FEATURE
#define FEATURE (default value)
#endif

To allow the assignment of a default if the configuration header doesn't
define a value for the option. IF you want the default to be something
other than 0, you need to do this.

My guess is that this is a common enough usage that breaking it would be
a big issue, so trying to aim for changing the interpretation if #if is
a very long term procedure.

On the other hand, since _If( expression )

Is currently a sequence reserved for the implementation, and I don't
know of any implementations that define it in a different manner, that
it would be possible to add as a conforming extension, and later into
the standard a sequence like:

_If( expression)
<code>
_Elif( expression )
<code>
_Else
<other code>
_Endif

As a way to put in conditional compilation that references constant
expressions that can include things like 'sizeof'

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


#142650

FromDavid Brown <david.brown@hesbynett.no>
Date2019-03-31 21:46 +0200
Message-ID<q7r5es$8ug$1@dont-email.me>
In reply to#142645
On 31/03/2019 21:09, Richard Damon wrote:
> On 3/31/19 2:17 PM, David Brown wrote:
>> On 30/03/2019 23:19, Keith Thompson wrote:
>>> Thiago Adams <thiago.adams@gmail.com> writes:
>>>> 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.
>>>
>>> The meaning of
>>>
>>> #if UNDEFINED_IDENTIFIER
>>>
>>> is currently well defined.  Treating it as a fatal error could easily
>>> break existing code.  (A Windows include directory is not likely to be a
>>> representative sample.)
>>>
>>> What would be the advantage of deprecating it?
>>>
>>
>> I think something like this would be extremely difficult to deprecate in
>> the language, given how often it is used (it is, as you say, perfectly
>> good coding).  (gcc "-Wundef" gives this behaviour, for those that want
>> it - such as me, if I can get away with it.)
>>
>> Personally, I much prefer to write:
>>
>> #ifdef IDENTIFIER
>>
>> or
>>
>> #if defined(IDENTIFIER)
>>
>> if it is possible for IDENTIFIER not to be defined - precisely because
>> it makes it clear to the reader that the IDENTIFIER might not be
>> defined.  And for the most part (where it is practically), I prefer to
>> write:
>>
>> #if FEATURE_ENABLED
>> ...
>> #endif
>>
>> with a configuration file saying:
>>
>> #define FEATURE_ENABLED 1
>>
>> or
>>
>> #define FEATURE_ENABLED 0
>>
>> This makes it a lot easier to find where this identifier is defined -
>> where the configuration is done.  It is easy to search for the file and
>> line that says this feature is not enabled, but very difficult to search
>> for where it is just left undefined.
>>
>>
>> But even though I like to write my own code this way, it's an entirely
>> different matter to say I think other people should code the way /I/ want.
> 
> I too prefer to use #if FEATURE instead of #ifdef FEATURE, as that
> allows the configuration file to list all the options with
> #define FEATURE 1 or
> #define FEATURE 0
> 
> but, due to the current rules, if the configuration file doesn't have
> any definition, then you get a default of not using the feature.

Yes.  (Though I like that gcc can, if the programmer specifically 
wishes, change those rules.)

> 
> It is also possible to add sequences like
> 
> #ifndef FEATURE
> #define FEATURE (default value)
> #endif
> 
> To allow the assignment of a default if the configuration header doesn't
> define a value for the option. IF you want the default to be something
> other than 0, you need to do this.

Yes.

It is also fine to write:

#ifndef FEATURE
#error Please define FEATURE as 0 or 1 explicitly
#endif

There is plenty of flexibility to suit everyone (except those that don't 
want other people to have flexibility...).

> 
> My guess is that this is a common enough usage that breaking it would be
> a big issue, so trying to aim for changing the interpretation if #if is
> a very long term procedure.

Agreed.

> 
> On the other hand, since _If( expression )
> 
> Is currently a sequence reserved for the implementation, and I don't
> know of any implementations that define it in a different manner, that
> it would be possible to add as a conforming extension, and later into
> the standard a sequence like:
> 
> _If( expression)
> <code>
> _Elif( expression )
> <code>
> _Else
> <other code>
> _Endif
> 
> As a way to put in conditional compilation that references constant
> expressions that can include things like 'sizeof'
> 

That could work as a compiler extension.

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


#142686

FromThiago Adams <thiago.adams@gmail.com>
Date2019-04-01 04:36 -0700
Message-ID<f6328937-7a2c-46d3-b16a-a1837e94bade@googlegroups.com>
In reply to#142643
On Sunday, March 31, 2019 at 3:17:34 PM UTC-3, David Brown wrote:
...
> I think something like this would be extremely difficult to deprecate in 
> the language, given how often it is used (it is, as you say, perfectly 
> good coding).  (gcc "-Wundef" gives this behaviour, for those that want 
> it - such as me, if I can get away with it.)

Very interesting flag (-Wundef).

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


#142754

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-04-02 17:47 -0700
Message-ID<05eed778-23c3-4ee4-ae76-8f9f99c5a116@googlegroups.com>
In reply to#142622
On Saturday, March 30, 2019 at 5:40:45 PM UTC-4, Thiago Adams wrote:
> 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.

After reading answer given below, ask yourself whether you're sure you
would have noticed a use of similar techniques. They're subtle, and if
you don't know what you're looking for, you might not notice them.

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

    #if __STDC_VERSION__ > 199001L
        #error This code relies upon features added in C99
    #endif

Since __STDC_VERSION__ will presumably be pre#defined by the
implementation in all future versions of the C standard, and the change
you propose will have no effect, even if approved, on compilers that
implement either K&R C or C90, your proposed change can't break this
particular example.

However, the basic principle applies to any macro name that might not be
#defined, but if it is #defined, is guaranteed to have a non-zero value,
if it's interpretation has been carefully designed to make it reasonable
to treat the un#defined case the same as other cases near 0. If your
proposal were accepted, it would require such code to be re-written in a
more clumsy fashion to work with the new version of the standard:

    #ifdef POSSIBLY_UNDEFINED_NUMERIC_MACRO
        #if  POSSIBLY_UNDEFINED_NUMERIC_MACRO > 5
            // Handle values of 6 or greater
        #endif
    #endif

That rewrite, while more complex, is arguably clearer, particularly
because many people are unfamiliar with this feature of the C
preprocessing phase. However, the C committee places a strong emphasis
on backwards compatibility, and since this is a feature that a fair
amount of existing code relies upon, it's unlikely that they would
approve any such change.

Another example: consider an implementation where, for instance, short
is 16 bits, int is 32 bits, long is 64 bits, and long long is 128 bits,
which supports int96_t using an extended integer type. How should such
an implementation implement the INT96() macro in <stdint.h>?

"Each invocation of one of these macros shall expand to an integer
constant expression suitable for use in #if preprocessing directives.
The type of the expression shall have the same type as would an
expression of the corresponding type converted according to the integer
promotions. The value of the expression shall be that of the argument."
(7.18.4p3)

INT8_C(), INT16_C() and INT32C() can leave their arguments unmodified:
they will be interpreted as integer constants and promoted to int, which
is the correct type. INT64_C() can paste an "L" suffix to the end of
it's argument, and INT128_C() can paste an "LL" suffix to the end of
it's argument.

    #define INT96_C(a) ((int96_t)a)

would do the right thing for in most contexts, but won't work in a #if
condition. Under the current standard, it becomes (0)a, which is a
syntax error. With your proposal, it would be a constraint violation,
which is just as useless.

An implementation could recognize an implementation-specific suffix for
int96_t constants. But an alternative approach that doesn't require any
language extensions, and has been used, is

    #define INT96_C(a) ((int96_t)+a)

Thus, when used in a preprocessing directive, INT96_C(1248) becomes
((0)+1248), an expression with the right value and the right type
(within #if conditions, integer expressions can only have the types
intmax_t and uintmax_t). Outside of preprocessing directives it becomes
an expression with both the right type and the right value.

Note that the specific types that I mentioned aren't important - all
that matters is that an implementation supports at least one extended
integer type, suitable for use in one of the standard typedefs, whose
promoted type is neither int, long, nor long long.

I've seen this same trick used for several other similar purposes: to
include a keyword or identifier in the normal expansion of a macro, but
have it disappear in a syntactically legal fashion when expanded within
a #if condition. However, this is the only case where I can remember
the details of why it was used.

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


#142770

FromThiago Adams <thiago.adams@gmail.com>
Date2019-04-03 05:31 -0700
Message-ID<eba505b1-bf63-4ab5-bce9-dc02b0f92e66@googlegroups.com>
In reply to#142754
On Tuesday, April 2, 2019 at 9:47:42 PM UTC-3, James Kuyper wrote:
> On Saturday, March 30, 2019 at 5:40:45 PM UTC-4, Thiago Adams wrote:
> > 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.
> 
> After reading answer given below, ask yourself whether you're sure you
> would have noticed a use of similar techniques. They're subtle, and if
> you don't know what you're looking for, you might not notice them.
> 
> > I think this behavior could be deprecated and generate warning
> > or error.
> 
>     #if __STDC_VERSION__ > 199001L
>         #error This code relies upon features added in C99
>     #endif
> 
> Since __STDC_VERSION__ will presumably be pre#defined by the
> implementation in all future versions of the C standard, and the change
> you propose will have no effect, even if approved, on compilers that
> implement either K&R C or C90, your proposed change can't break this
> particular example.

Yes.

 
> However, the basic principle applies to any macro name that might not be
> #defined, but if it is #defined, is guaranteed to have a non-zero value,
> if it's interpretation has been carefully designed to make it reasonable
> to treat the un#defined case the same as other cases near 0. If your
> proposal were accepted, it would require such code to be re-written in a
> more clumsy fashion to work with the new version of the standard:
> 
>     #ifdef POSSIBLY_UNDEFINED_NUMERIC_MACRO
>         #if  POSSIBLY_UNDEFINED_NUMERIC_MACRO > 5
>             // Handle values of 6 or greater
>         #endif
>     #endif
> 
> That rewrite, while more complex, is arguably clearer, particularly
> because many people are unfamiliar with this feature of the C
> preprocessing phase. However, the C committee places a strong emphasis
> on backwards compatibility, and since this is a feature that a fair
> amount of existing code relies upon, it's unlikely that they would
> approve any such change.

It would be deprecated first to give time for people update
the code. Just like if gcc -Wundef were the default mode.

"-Wundef
Warn if an undefined identifier is evaluated in an #if directive. 
Such identifiers are replaced with zero."


 
> Another example: consider an implementation where, for instance, short
> is 16 bits, int is 32 bits, long is 64 bits, and long long is 128 bits,
> which supports int96_t using an extended integer type. How should such
> an implementation implement the INT96() macro in <stdint.h>?
> 
> "Each invocation of one of these macros shall expand to an integer
> constant expression suitable for use in #if preprocessing directives.
> The type of the expression shall have the same type as would an
> expression of the corresponding type converted according to the integer
> promotions. The value of the expression shall be that of the argument."
> (7.18.4p3)
> 
> INT8_C(), INT16_C() and INT32C() can leave their arguments unmodified:
> they will be interpreted as integer constants and promoted to int, which
> is the correct type. INT64_C() can paste an "L" suffix to the end of
> it's argument, and INT128_C() can paste an "LL" suffix to the end of
> it's argument.
> 
>     #define INT96_C(a) ((int96_t)a)
> 
> would do the right thing for in most contexts, but won't work in a #if
> condition. Under the current standard, it becomes (0)a, which is a
> syntax error. With your proposal, it would be a constraint violation,
> which is just as useless.

At the first 'phase of deprecation', it would generate a warning.

In the future, if the proposal of integrating preprocessor was approved,
then the expansion would be a normal constant expression evaluated
at compile time.

My suggestion was deprecate first and change the meaning later.


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


#142777

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-04-03 06:46 -0700
Message-ID<d5b8148e-3717-4164-9393-d3e658e916d7@googlegroups.com>
In reply to#142770
On Wednesday, April 3, 2019 at 8:31:20 AM UTC-4, Thiago Adams wrote:
> On Tuesday, April 2, 2019 at 9:47:42 PM UTC-3, James Kuyper wrote:
> > On Saturday, March 30, 2019 at 5:40:45 PM UTC-4, Thiago Adams wrote:
...
> > > I did a search in windows include directory for #if identifier
> > > and I didn't find any usage where identifier was not defined.
> > 
> > After reading answer given below, ask yourself whether you're sure you
> > would have noticed a use of similar techniques. They're subtle, and if
> > you don't know what you're looking for, you might not notice them.
> > 
> > > I think this behavior could be deprecated and generate warning
> > > or error.
> > 
> >     #if __STDC_VERSION__ > 199001L
> >         #error This code relies upon features added in C99
> >     #endif
> > 
> > Since __STDC_VERSION__ will presumably be pre#defined by the
> > implementation in all future versions of the C standard, and the change
> > you propose will have no effect, even if approved, on compilers that
> > implement either K&R C or C90, your proposed change can't break this
> > particular example.
> 
> Yes.
> 
>  
> > However, the basic principle applies to any macro name that might not be
> > #defined, but if it is #defined, is guaranteed to have a non-zero value,
> > if it's interpretation has been carefully designed to make it reasonable
> > to treat the un#defined case the same as other cases near 0. If your
> > proposal were accepted, it would require such code to be re-written in a
> > more clumsy fashion to work with the new version of the standard:
> > 
> >     #ifdef POSSIBLY_UNDEFINED_NUMERIC_MACRO
> >         #if  POSSIBLY_UNDEFINED_NUMERIC_MACRO > 5
> >             // Handle values of 6 or greater
> >         #endif
> >     #endif
> > 
> > That rewrite, while more complex, is arguably clearer, particularly
> > because many people are unfamiliar with this feature of the C
> > preprocessing phase. However, the C committee places a strong emphasis
> > on backwards compatibility, and since this is a feature that a fair
> > amount of existing code relies upon, it's unlikely that they would
> > approve any such change.
> 
> It would be deprecated first to give time for people update
> the code. ...

I meant something a little stronger than that. It is my guess that the
committee will consider the backwards compatibility issue to be a far
more important consideration than any reason you've given so far for
making this change, and will therefore probably not even agree to
deprecate it.

...
> My suggestion was deprecate first and change the meaning later.

Yes, and my assessment is that, since there is existing code that
depends upon this behavior, you've given insufficiently strong reasons
to follow that suggestion. That's just a prediction, not a decision - I
have no decision-making power on this matter.

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


#142779

FromThiago Adams <thiago.adams@gmail.com>
Date2019-04-03 07:44 -0700
Message-ID<39acc9b9-e848-40a7-b350-8716725305d8@googlegroups.com>
In reply to#142777
On Wednesday, April 3, 2019 at 10:47:06 AM UTC-3, James Kuyper wrote:
> On Wednesday, April 3, 2019 at 8:31:20 AM UTC-4, Thiago Adams wrote:
> > On Tuesday, April 2, 2019 at 9:47:42 PM UTC-3, James Kuyper wrote:
> > > On Saturday, March 30, 2019 at 5:40:45 PM UTC-4, Thiago Adams wrote:
> ...
> > > > I did a search in windows include directory for #if identifier
> > > > and I didn't find any usage where identifier was not defined.
> > > 
> > > After reading answer given below, ask yourself whether you're sure you
> > > would have noticed a use of similar techniques. They're subtle, and if
> > > you don't know what you're looking for, you might not notice them.
> > > 
> > > > I think this behavior could be deprecated and generate warning
> > > > or error.
> > > 
> > >     #if __STDC_VERSION__ > 199001L
> > >         #error This code relies upon features added in C99
> > >     #endif
> > > 
> > > Since __STDC_VERSION__ will presumably be pre#defined by the
> > > implementation in all future versions of the C standard, and the change
> > > you propose will have no effect, even if approved, on compilers that
> > > implement either K&R C or C90, your proposed change can't break this
> > > particular example.
> > 
> > Yes.
> > 
> >  
> > > However, the basic principle applies to any macro name that might not be
> > > #defined, but if it is #defined, is guaranteed to have a non-zero value,
> > > if it's interpretation has been carefully designed to make it reasonable
> > > to treat the un#defined case the same as other cases near 0. If your
> > > proposal were accepted, it would require such code to be re-written in a
> > > more clumsy fashion to work with the new version of the standard:
> > > 
> > >     #ifdef POSSIBLY_UNDEFINED_NUMERIC_MACRO
> > >         #if  POSSIBLY_UNDEFINED_NUMERIC_MACRO > 5
> > >             // Handle values of 6 or greater
> > >         #endif
> > >     #endif
> > > 
> > > That rewrite, while more complex, is arguably clearer, particularly
> > > because many people are unfamiliar with this feature of the C
> > > preprocessing phase. However, the C committee places a strong emphasis
> > > on backwards compatibility, and since this is a feature that a fair
> > > amount of existing code relies upon, it's unlikely that they would
> > > approve any such change.
> > 
> > It would be deprecated first to give time for people update
> > the code. ...
> 
> I meant something a little stronger than that. It is my guess that the
> committee will consider the backwards compatibility issue to be a far
> more important consideration than any reason you've given so far for
> making this change, and will therefore probably not even agree to
> deprecate it.
> 
> ...
> > My suggestion was deprecate first and change the meaning later.
> 
> Yes, and my assessment is that, since there is existing code that
> depends upon this behavior, you've given insufficiently strong reasons
> to follow that suggestion. That's just a prediction, not a decision - I
> have no decision-making power on this matter.

I have an upgrade for my suggestion.

The current syntax is:

# if constant-expression new-line group

my suggestion is add a new option with { } around 
the expression and make the new rules apply in this 
context leaving unchanged the old rules for #if without { }.

#if { constant-expression } new-line group

and in general, not only for #if, the need for exclusive
line for preprocessor could be removed in many cases.

Then we could write:

#define M(a) \
  #if {sizeof(a) > 2} .. #endif

The need for _If that I was suggested before is not necessary.

I also would like to remove the need for \ #defines.

and have something like:

#macro M(a)

#end

At the end, keeping the compatibility we could make the language
much more powerful with simple rules.

So far I didn't mention hygienic macros, but this is also something
that could be considered with this integration.



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


#142787

FromThiago Adams <thiago.adams@gmail.com>
Date2019-04-03 09:46 -0700
Message-ID<6699a6ca-d851-4250-8bad-911d5f738cbf@googlegroups.com>
In reply to#142779
On Wednesday, April 3, 2019 at 11:44:42 AM UTC-3, Thiago Adams wrote:
[...]
> my suggestion is add a new option with { } around 
> the expression and make the new rules apply in this 
> context leaving unchanged the old rules for #if without { }.
> 
> #if { constant-expression } new-line group
> 
> and in general, not only for #if, the need for exclusive
> line for preprocessor could be removed in many cases.
> 
> Then we could write:
> 
> #define M(a) \
>   #if {sizeof(a) > 2} .. #endif


This sample has one pitfall that is the macro stringizing
operator #.
To work, we will have to change the rules.

instead of error '#' is not followed by a macro parameter
this should ignore in case # is followed by something that
is not argument.


I have adapted many times my suggestion, and also this may 
be off topic.
The thing that does not change is my view that in some way
(that is not 100% clear) we can rethink about the preprocessor
and update it.






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


#142570

Fromscott@slp53.sl.home (Scott Lurndal)
Date2019-03-28 21:29 +0000
Message-ID<F0bnE.195294$j34.102346@fx14.iad>
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)
>

In days of lore, a program called cpp did the preprocessing, passing
the results to a program called c0 for lexical and semantic analysis
and a program called c1 for code generation (and optionally a program
called c2 for peephole and other optimizations).

A few years later, c0/c1/c2 were combined into a single executable, but
cpp was still used as the pre-processor.   In that case, when cpp saw
the #pragma directive, it would pass it through to the compiler (much
like the #line directives passed by cpp to the compiler so the compiler
could print accurate line numbers with error messages and could generate
run-time metadata for a debugger).  The compiler would see #pragma starting
a line, parse it, and honor it (or generate an error if unrecognized).

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


#142589

FromThiago Adams <thiago.adams@gmail.com>
Date2019-03-29 07:32 -0700
Message-ID<562d508a-2f87-48c1-9220-3ca132d5db83@googlegroups.com>
In reply to#142567
On Thursday, March 28, 2019 at 5:59:46 PM UTC-3, Thiago Adams wrote:
> What is funny is that compiler configuration like pragma pack
> and many others are done using preprocessor.

The other thing I think it's funny if __func__ .

Many programmers will thing __func__ in the same way they
think about __LINE__ and __FILE__, but the first in from
compiler and the later from preprocessor.

We could have much more options like 
__var_name__ (x)
__var_type__ (x)

We said the compiler flags were passed using pragmas.
If [[attributes]] were added into C, then this added a new
way to do that. 

  switch (n) {
    case 1:
     [[fallthrough]];
    case 3: // no warning on fallthrough
  ..
  }

We already have #pragma and _Pragma.


_Pragma doesn't look as preprocessor.

We could have just.

 switch (n) {
    case 1:
     _Pragma("fallthrough");
    case 3: // no warning on fallthrough
  ..

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

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


csiph-web