public inbox for linux-man@vger.kernel.org
 help / color / mirror / Atom feed
From: "Alejandro Colomar (man-pages)" <alx.manpages@gmail.com>
To: "G. Branden Robinson" <g.branden.robinson@gmail.com>
Cc: linux-man@vger.kernel.org
Subject: Re: Bold and italics, semantics and constness (was: [PATCH v2] mctp.7: Add man page for Linux MCTP support)
Date: Mon, 22 Nov 2021 17:00:10 +0100	[thread overview]
Message-ID: <ba2213cc-63bf-0b2d-0964-3a80dc37e0dd@gmail.com> (raw)
In-Reply-To: <20211122135240.frxwgjbif72akv3n@localhost.localdomain>

[I removed Michael; not to spam him :]

On 11/22/21 14:52, G. Branden Robinson wrote:
> Hi Alex,
> 
> At 2021-11-22T12:50:55+0100, Alejandro Colomar (man-pages) wrote:
> [much snipped]
>> I have had a very bad (and luckily short) experience with
>> Lean/Agile/XP/MVP.
> 
> Well, they're all different things.  Supposedly.  Perhaps not.  :-|

My experience was with Agile/Scrum.  I've read about the others, and
they all seem variants of a similar thing.  I can't talk about the
others so much, since I haven't experienced them, but prefer to live
ignorant.  For agile, I can say that, for how my brain works internally,
it just destroys my performance, and my happiness.  Most job offers I
see today, either say Agile, or say nothing at all; I rarely see any of
the others being mentioned in job descriptions.  If I see agile, I will
very likely discard the offer.

> 
>> If I can help sabotage that, I will happily and intentionally do.
> 
> Hustlers will always be flogging "revolutionary" innovations to
> managers, and managers will always suck them up.  It's not even that
> there are never any worthwhile ideas in these manifestos, it's just that
> you can fit that subset on an index card and the margins in publishing
> index cards isn't high enough to attract anyone's interest.

My opinion is (of course I'm not a manager, and wouldn't like to be):
let the programmers program however they are more comfortable.  Each
brain works in a different manner.  Forcing one way will, at best,
reduce performance.  If anything, a manager should recommend reading
about a methodology (maybe after reading about it, the programmer likes
it), not impose it.  I've been in interviews where I've been asked a lot
about if at my current job they used Agile and how much they implemented
of it, and almost no questions about my programming skills...

> 
>> Are we talking about libc, or C documentation in general?  Because
>> libc doesn't have any 'const' variables at all, at least that I know
>> of.
> 
> I was speaking in general, but the Austin Group is kicking around a
> const struct member for 'tm' right now.[1]
> 
>> So we don't even need to care in the Linux man-pages.  Maybe manual
>> pages for other C libraries can better decide what to do with those.
> 
> I have this sick idea that everything that can be const, should be.
> It's better for both parallelism and, generally, robustness.
> 
>> I think we're talking about 2 different things:
>>
>> - 'const' variables
>> - pointers to 'const'
>>
>> 'const' variables can never be cast away.  It's an error.
> 
> Agreed.
> 
>> $ cat pointer_to_const.c
>> void bar(const int *p)
>> {
>> 	int *q;
>>
>> 	q = (int *)p;
>> 	*q = 3;
>> }
>>
>> This is allowed by the compiler, but it is Undefined Behavior _unless_
>> the variable pointed to by 'p' is really not const.  Casting away
>> const is IMO also braindamaged, so I don't consider it a valid thing.
> 
> I remember having to do this on rare occasions, but don't recollect the
> details.  I'm uncertain whether I was working around a bad design or
> just being a bad programmer.

I also remember doing this.  There's a valid scenario:

Callbacks where the interface is generic (void *).  In that case, you
need to provide a prototype that matches the interface, and even if you
don't modify the input, you need to provide a function that accepts a
non-const, to avoid having to cast the function pointer, which would be
even more dangerous.

Then, when you pass const data through the (void *), since you know it
won't be modified (you wrote the callback), you're safe casting it to
(void *).

I think there's no better way around that than casting to (void *).
However, that's rare enough not to be alarmed.

> 
> There is of course the constant pointer to a constant object.
> 
> const int * const foo;
> 
> ...which, because people insist that type qualifiers must come before
> type names so that declarations read slightly more like English, leads
> them to ugly constructions like
> 
> const int *const foo;

I like it this way.  I may be inconsistent, but I'm used to that way :)
I've read an ad-hoc argument that you can read it right-to-left as:
"foo is a const pointer to an int constant."

To try to justify myself, maybe, my brain considers 'const' to be a more
important piece of information than 'int', which is normally already
obvious by the context.  Since 'const' is closer to the left-side blank
it is more easily parsed by my eyes... just trying to make some sense.

> 
> to remind themselves which way the operator binds...when they _could_
> just write things so that a simpler "noun-adjective" rule leads to a
> correct parse in meatspace.
> 
> int const * const foo;

Yes, every objective argument would recommend this form, but
subjectively, it is ugly to my eyes :p

> 
> Klemens flogs this in _21st Century C_ (O'Reilly).
> 
>> One of the things that I like from C++ is that they correctly
>> implemented const.  Hey, "asd" is 'char *' in C, but of course if you
>> modify it, demons fly out of your nose!
> 
> With -fwritable-strings, they stay inside and poke your sinuses with
> pitchforks...surely an improvement(?).

Sometimes I would just like to see backwards compatibility to be
ignored.  There are things that are just wrong.  If C30 decided to make
const-correctness as it should have been from the beginning, and made
string literals to be (const char *), old programs that would want to
recompile with C30 would need to be fixed, but how much of a problem
would that be?  There's always the option to specify -std=c89 if you
want to avoid fixing some program.

But I also like how slow the C standard advances.  That way they avoid
adding much of the insane stuff that C++ adds.  Even the C standard adds
things that I very much doubt they were ever needed (static for array
parameters?).  So in the end, having so few changes is a good thing.

> 
>> Going back to formatting:
>>
>> Pointers to const are just variables.  Their value is the address of
>> some const, but that's not important.  The important thing is that
>> they are variables, and therefore, you use italics with them.
> 
> Okay, I'm with you so far...
> 
>> So the only thing that IMHO should be bold (apart from constants and
>> macros that expand to constants) should be global 'const' variables:
>>
>> const int FOO = 3;
>>
>> which some people prefer over macros, and which in C++, one could
>> write as:
>>
>> constexpr int FOO = 3;
>>
>> In the case above, I don't see a reason why one would want to
>> differentiate that from say
>>
>> #define FOO  3
> 
> It's a good argument.  The only ones that I can marshal against it are
> that in the first case, 'FOO' is a C object and an lvalue (which is
> almost saying the same thing).  I don't know C++ well enough to address
> the second example, but I'm learning C++98 so that I can deal better
> with the groff code base, which is written "Annotated Reference Manual
> C++", a dialect that is as old as groff itself (1990).

The second one guarantees that FOO evaluates to a constant at
compile-time.  Therefore, you can for example use it to initialize
non-VLA array sizes.

I use C++ as "C with extensions" (not even "C with classes").  I like
some of it's extensions so much that I use them in C:

#if !defined(__cplusplus)
#define auto  __auto_type
#endif

If it confuses someone, I'm sorry :)

> 
>> But in function parameters, 'const' is useless in variables, since
>> they already got a copy, so they won't alter the original.  And in
>> pointers, const applies to the pointee, but the pointer itself is
>> variable, so italics.
> 
> I think of 'const' in function definitions as asserting invariants.
> Consider the following example, where I use two consts that it sounds
> like you would not, to prevent 2 different forms of stupidity.

In the function definiton, it may be useful (but not so much).
In the function prototype, it is useless.

> 
>     void func(int const foo, int const * const bar) {
>     //void func(int const foo, int const * bar) {
>     //void func(int foo, int * bar) {
>         foo = 3;  // prevented by 'int const foo'
>         *bar = 4; // prevented by 'int const * bar'
>         bar++;    // prevented by 'int const * const bar'
>     }

I tend to write functions so short (usually fit a screen; < 24 LOC) that
you can see if you're doing something really stupid.  In something like
glibc's source code, where you see functions with more than 200 LOC,
then const may make sense.

I also very consistently differentiate array syntax from pointer syntax,
so I rarely use ++ to advance pointers.

I'd write:

     void func(int foo, const int *bar, int baz[foo])
     {
	 int i = 0;

         foo = 3;  // I'm editing my own copy. There's not much danger
                   // If I'm really stupid in the implementation,
                   // that has nothing to do with the interface.
         *bar = 4; // prevented by 'const int *bar'
         bar++;    // Having a clear distinction in the prototype
                   // makes this mistake very rare.
         baz[i++] = 5;
     }

In glibc code, for example, they don't use const variables in the
prototypes, but they use them in the definitions.  I'd rather write
shorter functions, and a more readable coding style would also help.

I like to limit prototypes to info that is relevant to the interface,
and I also like the definition to be identical to the prototype.

I limit my usage of const to interfaces, and to achieve
const-correctness.  Avoiding silly mistakes in the implementation of an
algorithm creates too much noise to my taste.

> 
>     int main(int argc, char *argv[]) {
>         int foo = 1;
>         int bar = 2;
>         func(foo, &bar);
>         (void) printf("foo=%d, bar=%d\n", foo, bar);
>     }
> 
> When you're writing a parser (groff has many of them), you pass 'const
> char *' around all the time.  Often these pointers are ones you got back
> from strtok() or similar.  You can pass them to a function to do some
> kind of validity checking--but do you want that pointer advanced through
> the string by the helper function, or not?  If not, then you can make
> the pointer const, and rely on the helper function to make a copy of it
> if necessary.  If you do want it to advance the pointer, for instance if
> it's a function that skips comments and/or white space, then you can
> pass a non-const pointer, and it will give you back a pointer that is
> aimed at the next valid input token.

By returning the pointer?  Or by a pointer-to-pointer?  Otherwise, the
edit is only visible to the copy of the pointer.

Regards,
Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

      reply	other threads:[~2021-11-22 16:00 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-11  1:53 [PATCH v2] mctp.7: Add man page for Linux MCTP support Jeremy Kerr
2021-11-11 21:38 ` Alejandro Colomar (man-pages)
2021-11-12  1:12   ` Jeremy Kerr
2021-11-12 18:45     ` Alejandro Colomar (man-pages)
2021-11-12 19:40       ` G. Branden Robinson
2021-11-12 20:07         ` Alejandro Colomar (man-pages)
2021-11-12 20:07           ` Alejandro Colomar (man-pages)
2021-11-18  5:08       ` Jeremy Kerr
2021-11-22 16:35         ` Alejandro Colomar (man-pages)
2021-11-12  9:35   ` G. Branden Robinson
2021-11-12 19:50     ` Alejandro Colomar (man-pages)
2021-11-22  9:06       ` Bold and italics, semantics and constness (was: [PATCH v2] mctp.7: Add man page for Linux MCTP support) G. Branden Robinson
2021-11-22 11:50         ` Alejandro Colomar (man-pages)
2021-11-22 13:52           ` G. Branden Robinson
2021-11-22 16:00             ` Alejandro Colomar (man-pages) [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ba2213cc-63bf-0b2d-0964-3a80dc37e0dd@gmail.com \
    --to=alx.manpages@gmail.com \
    --cc=g.branden.robinson@gmail.com \
    --cc=linux-man@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox