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


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

Double-underline-itis

Started byBartC <bc@freeuk.com>
First post2017-02-28 23:44 +0000
Last post2017-04-16 18:45 -0700
Articles 12 — 7 participants

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


Contents

  Double-underline-itis BartC <bc@freeuk.com> - 2017-02-28 23:44 +0000
    Re: Double-underline-itis supercat@casperkitty.com - 2017-02-28 15:54 -0800
    Re: Double-underline-itis Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-01 01:19 +0000
      Re: Double-underline-itis David Brown <david.brown@hesbynett.no> - 2017-03-01 09:11 +0100
      Re: Double-underline-itis BartC <bc@freeuk.com> - 2017-03-01 11:45 +0000
        Re: Double-underline-itis Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-01 12:30 +0000
          Re: Double-underline-itis BartC <bc@freeuk.com> - 2017-03-01 13:04 +0000
            Re: Double-underline-itis Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-01 15:29 +0000
              Re: Double-underline-itis gazelle@shell.xmission.com (Kenny McCormack) - 2017-03-01 15:47 +0000
            Re: Double-underline-itis Keith Thompson <kst-u@mib.org> - 2017-03-01 09:30 -0800
              Re: Double-underline-itis supercat@casperkitty.com - 2017-03-01 10:14 -0800
              Re: Double-underline-itis Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-16 18:45 -0700

#105184 — Double-underline-itis

FromBartC <bc@freeuk.com>
Date2017-02-28 23:44 +0000
SubjectDouble-underline-itis
Message-ID<o951ti$ch6$1@dont-email.me>
I came across this declaration in some Linux header:

  extern int mbtowc (wchar_t *__restrict __pwc,
           const char *__restrict __s, size_t __n) __THROW;

There are thousands just the same. I can understand the double-underline 
prefix used for implementation names that may clash with those in the 
user namespace.

But what's with the double-underline on the parameter names? They 
shouldn't clash with anything. (And here, I assumed __pwc was yet 
another attribute that the implementation thinks is needed.)

Sometimes, as well as the double-underline at the start, they need to 
have one at the end too, such as '__restrict__' (what's wrong with just 
'restrict', if you need to have it all?).

Underlines are hard to see and tend to run together so you can't tell 
easily if there are two or three.

Since $ isn't used much, what would have been wrong with that? It's not 
pretty but at least you can see it!

-- 
bartc

[toc] | [next] | [standalone]


#105188

Fromsupercat@casperkitty.com
Date2017-02-28 15:54 -0800
Message-ID<d27b7334-b5f4-4ce7-b03a-b3315384b5d8@googlegroups.com>
In reply to#105184
On Tuesday, February 28, 2017 at 5:44:48 PM UTC-6, Bart wrote:
> But what's with the double-underline on the parameter names? They 
> shouldn't clash with anything. (And here, I assumed __pwc was yet 
> another attribute that the implementation thinks is needed.)

User code is allowed to declare macros with almost any names the user sees
fit, and might do so prior to including standard headers.  If user code
started with

   #define fmt "(Quack! My favorite number is %d)"
   #include <stdio.h>

and the definition for printf were

    int printf(char const *restrict fmt, ...);

then compilation of the header would fail.

Such constructs don't generally cause trouble, but I don't think they're
conforming when they use non-reserved identifiers.

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


#105197

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-03-01 01:19 +0000
Message-ID<87tw7doktz.fsf@bsb.me.uk>
In reply to#105184
BartC <bc@freeuk.com> writes:

> I came across this declaration in some Linux header:
>
>  extern int mbtowc (wchar_t *__restrict __pwc,
>           const char *__restrict __s, size_t __n) __THROW;
>
> There are thousands just the same. I can understand the
> double-underline prefix used for implementation names that may clash
> with those in the user namespace.
>
> But what's with the double-underline on the parameter names? They
> shouldn't clash with anything.

That's why the underscores are there.  Without them, the names could
clash with user-defined macros.

> (And here, I assumed __pwc was yet
> another attribute that the implementation thinks is needed.)

Why?  I would assume it's just the parameter name unless I had strong
evidence that it was not.

> Sometimes, as well as the double-underline at the start, they need to
> have one at the end too, such as '__restrict__' (what's wrong with
> just 'restrict', if you need to have it all?).

__restrict__ can be #defined away when processing the header with a
pre-1999 version of C.  You can't do that with restrict because it's not
a name reserved to the implementation.  Obviously one could use
different headers for different C versions, but this method is simple
and effective.

> Underlines are hard to see and tend to run together so you can't tell
> easily if there are two or three.

I don't have that problem.  _, __ and ___ all look very different to
me.  Maybe it's the font I use -- there is a slight gap between
consecutive underscores.

> Since $ isn't used much, what would have been wrong with that? It's
> not pretty but at least you can see it!

-- 
Ben.

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


#105224

FromDavid Brown <david.brown@hesbynett.no>
Date2017-03-01 09:11 +0100
Message-ID<o95vkj$d16$1@dont-email.me>
In reply to#105197
On 01/03/17 02:19, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:
> 
>> I came across this declaration in some Linux header:
>>
>>  extern int mbtowc (wchar_t *__restrict __pwc,
>>           const char *__restrict __s, size_t __n) __THROW;
>>
>> There are thousands just the same. I can understand the
>> double-underline prefix used for implementation names that may clash
>> with those in the user namespace.
>>
>> But what's with the double-underline on the parameter names? They
>> shouldn't clash with anything.
> 
> That's why the underscores are there.  Without them, the names could
> clash with user-defined macros.
> 
>> (And here, I assumed __pwc was yet
>> another attribute that the implementation thinks is needed.)
> 
> Why?  I would assume it's just the parameter name unless I had strong
> evidence that it was not.
> 
>> Sometimes, as well as the double-underline at the start, they need to
>> have one at the end too, such as '__restrict__' (what's wrong with
>> just 'restrict', if you need to have it all?).
> 
> __restrict__ can be #defined away when processing the header with a
> pre-1999 version of C.  You can't do that with restrict because it's not
> a name reserved to the implementation.  Obviously one could use
> different headers for different C versions, but this method is simple
> and effective.

There is also the opposite effect.  "restrict" can be #defined to
anything you want in pre-C99 or C++, so if the header used "restrict" it
would not work in pre-C99 modes, or C++ modes.  But gcc (and probably
clang, and maybe other compilers) allows restricted pointers in C++ mode
and other C modes, using "__restrict__" instead of "restrict".  So by
using "__restrict__" rather than "restrict", the header works for a
wider variety of compiler modes.

(Not that "restrict" in a function declaration does much other than
document the restriction, as has been discussed on another thread.)

> 
>> Underlines are hard to see and tend to run together so you can't tell
>> easily if there are two or three.
> 
> I don't have that problem.  _, __ and ___ all look very different to
> me.  Maybe it's the font I use -- there is a slight gap between
> consecutive underscores.
> 
>> Since $ isn't used much, what would have been wrong with that? It's
>> not pretty but at least you can see it!
> 

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


#105230

FromBartC <bc@freeuk.com>
Date2017-03-01 11:45 +0000
Message-ID<o96c5h$l84$1@dont-email.me>
In reply to#105197
On 01/03/2017 01:19, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:
>
>> I came across this declaration in some Linux header:
>>
>>  extern int mbtowc (wchar_t *__restrict __pwc,
>>           const char *__restrict __s, size_t __n) __THROW;
>>
>> There are thousands just the same. I can understand the
>> double-underline prefix used for implementation names that may clash
>> with those in the user namespace.
>>
>> But what's with the double-underline on the parameter names? They
>> shouldn't clash with anything.
>
> That's why the underscores are there.  Without them, the names could
> clash with user-defined macros.

Yes, that's what supercat said. But then, macros can cause all sorts of 
mischief. Anyone producing a header file for a library, and wishing to 
use parameter names in function declarations, would also be at risk of 
having those names clashing with macros declared before the header.

What can do they do? Use __ prefixes too? That would partly defeat the 
purpose of using parameter names to document their uses, and would 
clutter up the code. And __ is probably reserved for the implementation, 
so they could then clash with macros in the standard headers.

>> (And here, I assumed __pwc was yet
>> another attribute that the implementation thinks is needed.)
>
> Why?  I would assume it's just the parameter name unless I had strong
> evidence that it was not.

(I was looking for what was causing my parsing of the declaration to 
fail, I saw __pwc and declared that as another blank macro. As it turned 
out, wchar_t wasn't defined some reason. Eventually I'll have my own 
headers without any of these problems.

As it is, I have to painstakingly scan along looking for commas before I 
can even see how many parameters there are. Written in a saner manner:

   extern int mbtowc (wchar_t dest, char* source, size_t n);

Ah! Now it's obvious, even with those ugly "_t" suffixes; it presumably 
copies source to dest converting UTF8 or whatever to a wide-character 
array. Only the exactly meaning of n is unclear, but I would assume it's 
the maximum capacity of dest.

>> Sometimes, as well as the double-underline at the start, they need to
>> have one at the end too, such as '__restrict__' (what's wrong with
>> just 'restrict', if you need to have it all?).
>
> __restrict__ can be #defined away when processing the header with a
> pre-1999 version of C.  You can't do that with restrict because it's not
> a name reserved to the implementation.  Obviously one could use
> different headers for different C versions, but this method is simple
> and effective.

You mean that

    #define restrict

won't work because someone could have....

I don't even understand the problem. These are system headers, designed 
to work with a particular implementation, so will know whether 
'restrict' is supported or not. What's the point of such a keyword being 
introduced if it then goes onto use something else?

Or do the headers know the implementation doesn't recognise restrict? 
That's hard to believe because my set of gcc headers use __restrict too.

(And they seem to favour a single underline for parameter names. So a 
sort of primitive unary counting system:

    abc   0, user identifier
   _abc   1, implementation, grade 1?
  __abc   2, implementation, grade 2?
___abc   3, reserved, or system identifier _abc with __ prefix?
  __abc__ ? I give up!)

>> Underlines are hard to see and tend to run together so you can't tell
>> easily if there are two or three.
>
> I don't have that problem.  _, __ and ___ all look very different to
> me.  Maybe it's the font I use -- there is a slight gap between
> consecutive underscores.

In my own editor, in Notepad, in SciTe, in the C highlighting of both 
Pastebin and Github, and in my Thunderbird newsreader, underlines run 
together. Only with a couple of things I tried in Ubuntu was there a 
miniscule gap of what looked to be one pixel.

(Actually, that might also be the case in Windows; if I magnify the 
screen pixels, then I can see a slight greyish discontinuity between the 
_ characters. Probably an effect of character smoothing. But they still 
look like they run together.)

--
___bart_c

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


#105234

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-03-01 12:30 +0000
Message-ID<878topnpqm.fsf@bsb.me.uk>
In reply to#105230
BartC <bc@freeuk.com> writes:

> On 01/03/2017 01:19, Ben Bacarisse wrote:
>> BartC <bc@freeuk.com> writes:
>>
>>> I came across this declaration in some Linux header:
>>>
>>>  extern int mbtowc (wchar_t *__restrict __pwc,
>>>           const char *__restrict __s, size_t __n) __THROW;
>>>
>>> There are thousands just the same. I can understand the
>>> double-underline prefix used for implementation names that may clash
>>> with those in the user namespace.
>>>
>>> But what's with the double-underline on the parameter names? They
>>> shouldn't clash with anything.
>>
>> That's why the underscores are there.  Without them, the names could
>> clash with user-defined macros.
>
> Yes, that's what supercat said. But then, macros can cause all sorts
> of mischief. Anyone producing a header file for a library, and wishing
> to use parameter names in function declarations, would also be at risk
> of having those names clashing with macros declared before the header.

I'm not sure what your point is.  You asked a question and I tried to
answer it (in fact I'd say I did answer it).  Are you saying that system
headers should not take this into account because some other header
might not bother?

> What can do they do?

They should either not use names in the header or document the names
used so annt one #defining one of them prior to including the header
will know what's gone wrong.

<snip>
>>> Sometimes, as well as the double-underline at the start, they need to
>>> have one at the end too, such as '__restrict__' (what's wrong with
>>> just 'restrict', if you need to have it all?).
>>
>> __restrict__ can be #defined away when processing the header with a
>> pre-1999 version of C.  You can't do that with restrict because it's not
>> a name reserved to the implementation.  Obviously one could use
>> different headers for different C versions, but this method is simple
>> and effective.
>
> You mean that
>
>    #define restrict
>
> won't work because someone could have....
>
> I don't even understand the problem. These are system headers,
> designed to work with a particular implementation, so will know
> whether 'restrict' is supported or not. What's the point of such a
> keyword being introduced if it then goes onto use something else?

Many implementations support various C standards.  As I said, you could
include a different header for C90, C99 and so on but it's easier to
#define __restrict__ to either nothing or restrict depending on the
language version.

<snip>
-- 
Ben.

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


#105235

FromBartC <bc@freeuk.com>
Date2017-03-01 13:04 +0000
Message-ID<o96gp9$d8n$1@dont-email.me>
In reply to#105234
On 01/03/2017 12:30, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:

>> You mean that
>>
>>    #define restrict
>>
>> won't work because someone could have....
>>
>> I don't even understand the problem. These are system headers,
>> designed to work with a particular implementation, so will know
>> whether 'restrict' is supported or not. What's the point of such a
>> keyword being introduced if it then goes onto use something else?
>
> Many implementations support various C standards.  As I said, you could
> include a different header for C90, C99 and so on but it's easier to
> #define __restrict__ to either nothing or restrict depending on the
> language version.

I've just come across __signed__! How many C systems don't support 'signed'?

    typedef __signed__ char __s8;
    typedef unsigned char __u8;

Is this so __signed__ could be defined as 'unsigned' according to some 
compiler option? That seems unlikely when you declaring distinct s8 and 
u8 types.

(In a file from a Linux set of includes, one of various assorted headers 
that get loaded even when just using a handful of standard headers in 
the user-code. include\asm-generic\int-ll64.h

This was just after I had to 'remove' one time.h because it didn't 
define clock(). But there were 4 other time.h files in sub-directories, 
so no worries!

What a mess these system headers are. I hadn't realised they were so 
Heath Robinson, looking like a bunch of hacks put together to meet some 
deadline, instead of something more permanent.

Anyway these headers do seem to rely heavily on the use of "__" prefixes 
absolutely everywhere. And, for some reason that I'm not sure has been 
explained yet, on "__" suffixes.)

-- 
Bartc

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


#105254

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-03-01 15:29 +0000
Message-ID<87wpc9m2w5.fsf@bsb.me.uk>
In reply to#105235
BartC <bc@freeuk.com> writes:

> On 01/03/2017 12:30, Ben Bacarisse wrote:
>> BartC <bc@freeuk.com> writes:
>
>>> You mean that
>>>
>>>    #define restrict
>>>
>>> won't work because someone could have....
>>>
>>> I don't even understand the problem. These are system headers,
>>> designed to work with a particular implementation, so will know
>>> whether 'restrict' is supported or not. What's the point of such a
>>> keyword being introduced if it then goes onto use something else?
>>
>> Many implementations support various C standards.  As I said, you could
>> include a different header for C90, C99 and so on but it's easier to
>> #define __restrict__ to either nothing or restrict depending on the
>> language version.
>
> I've just come across __signed__! How many C systems don't support
> 'signed'?

Why do you assume is about support?  My first reaction when I see
something like this that I don't understand is that it's probably a my
fault.  Yes, there is often junk in these files but there is often stuff
I can't be sure about because it's solving a problem I've not yet
grasped.

<snip>
-- 
Ben.

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


#105258

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2017-03-01 15:47 +0000
Message-ID<o96qef$pqi$1@news.xmission.com>
In reply to#105254
In article <87wpc9m2w5.fsf@bsb.me.uk>,
Ben Bacarisse  <ben.usenet@bsb.me.uk> wrote:
...
>Why do you assume is about support?  My first reaction when I see
>something like this that I don't understand is that it's probably a my
>fault.  Yes, there is often junk in these files but there is often stuff
>I can't be sure about because it's solving a problem I've not yet
>grasped.

Given your situation in life, I think that's a very reasonable position for
you to take.  Man's got to know his limitations...!

-- 
"The party of Lincoln has become the party of John Wilkes Booth."

	- Carlos Alazraqui -

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


#105285

FromKeith Thompson <kst-u@mib.org>
Date2017-03-01 09:30 -0800
Message-ID<lnd1e0dhw0.fsf@kst-u.example.com>
In reply to#105235
BartC <bc@freeuk.com> writes:
[...]
> I've just come across __signed__! How many C systems don't support 'signed'?
>
>     typedef __signed__ char __s8;
>     typedef unsigned char __u8;
[...]

The "signed" keyword and the signed char type were, IIRC, introduced
by ANSI C in 1989.  A header designed to work with both pre-ANSI
and ANSI C would have to have some way of dealing with that.  And
since the header still works even with C11 (as long as __signed__
is defined properly), there's not much motivation to fix it --
unless you wrongly assume that headers are intended as end user
documentation.

The use of __s8 and __u8, rather than the standard int8_t and
uint8_t, already implies that this is from an old legacy header.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#105293

Fromsupercat@casperkitty.com
Date2017-03-01 10:14 -0800
Message-ID<29320219-8218-4e7a-be6e-91a41aaeac9f@googlegroups.com>
In reply to#105285
On Wednesday, March 1, 2017 at 11:30:21 AM UTC-6, Keith Thompson wrote:
> BartC writes:
> [...]
> > I've just come across __signed__! How many C systems don't support 'signed'?
> >
> >     typedef __signed__ char __s8;
> >     typedef unsigned char __u8;
> [...]
> 
> The "signed" keyword and the signed char type were, IIRC, introduced
> by ANSI C in 1989.  A header designed to work with both pre-ANSI
> and ANSI C would have to have some way of dealing with that.  And
> since the header still works even with C11 (as long as __signed__
> is defined properly), there's not much motivation to fix it --
> unless you wrongly assume that headers are intended as end user
> documentation.
> 
> The use of __s8 and __u8, rather than the standard int8_t and
> uint8_t, already implies that this is from an old legacy header.

Client code written for systems where "char" is signed might expect
that a function expecting a const pointer to an array of 8-bit signed
values would accept a pointer to a string literal.  Even systems where
"char" is signed, however, will not allow implicit conversions from
string literals to "signed char const *".

I think the Standard should have allowed implementations to, at their
option, treat as identical, types which have precisely-matching
representations and semantics.  Treating "char" and "signed char" identically
in such cases would make some implementations simpler, and would not affect
the meaning of any program upon which the Standard would impose any
requirements.  While some kinds of type incompatibility would be indicative
of possible logic problems (e.g. between an unsigned "char" type and a
"signed char" type), I see no reason to expect that would be true in cases
where the involved types have identical representations and are treated
identically in every way (including aliasing).

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


#108188

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-04-16 18:45 -0700
Message-ID<kfna87f958k.fsf@x-alumni2.alumni.caltech.edu>
In reply to#105285
Keith Thompson <kst-u@mib.org> writes:

> BartC <bc@freeuk.com> writes:
> [...]
>> I've just come across __signed__!  How many C systems don't
>> support 'signed'?
>>
>>     typedef __signed__ char __s8;
>>     typedef unsigned char __u8;
>
> [...]
>
> The "signed" keyword and the signed char type were, IIRC, introduced
> by ANSI C in 1989.  A header designed to work with both pre-ANSI
> and ANSI C would have to have some way of dealing with that.  And
> since the header still works even with C11 (as long as __signed__
> is defined properly), there's not much motivation to fix it --
> unless you wrongly assume that headers are intended as end user
> documentation.
>
> The use of __s8 and __u8, rather than the standard int8_t and
> uint8_t, already implies that this is from an old legacy header.

It probably is from an old header, but using __s8 and __u8 (as
opposed to int8_t and uint8_t) doesn't necessarily imply that.
The __u8 and __s8 types, as typedef'ed above, are more widely
applicable than the [u]int8_t types, for a variety of reasons.
Presumably someone concerned with maximizing portability
would be aware of such concerns.

[toc] | [prev] | [standalone]


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


csiph-web