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. :-| > 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. > 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. 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; 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; 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(?). > 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). > 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. 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' } 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. Regards, Branden [1] https://austingroupbugs.net/view.php?id=1533#c5532