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 | 15 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 2 of 2 — ← Prev page 1 [2]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2019-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2019-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