[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/