Modern C for Fedora (and the World)
lwn.net
lwn.net
Please no. In C++ this only makes sense when you have huge templated types such as iterators etc. Or inside templates where the types are not fixed.
Neither exist in C. It is just a distraction with no benefits in C.
I suspect that a C++-like auto could be of benefit in conjunction with that stuff.
char x = 1, y = 2;
auto var = x * y; // var inferred as int, due to promoted typeauto i = 0.0;
i is a double in C23 but an int in earlier version. Please don't use C23.
Though realistically if this looks like a problem it's a trivial compiler diagnostic. "Would this thing have a different type in C23 to earlier? Emit a warning, promotable to error".
The whole changes meaning panic is rather overdone and mostly acts to stop C improving over time.
Lots of stuff is valid and gets warnings on request, like `if (a = b)`, or anything where people get precedence or aliasing rules often enough that someone bothered to patch the compiler.
In the rare case where someone used 'auto type foo' you'll get compiler errors and can easily fix those.
I have never actually seen auto used in a C code base.
auto float f;
so a search and replace would break that code.
auto tautology = sizeof("automatons are on auto");
but int float f; is not a big one: The compiler will flag it as a syntax error, and you fix it as it comes.That's one strategy. It has consequences, such as keeping around K&R declarations and implicit pointer/int conversion for decades after they started being warned against. Other strategies may have merit.
The problem isn't merely gaining or losing features or syntax, it's changing the meaing and behavior of an existing thing.
Code is the definitive source of truth for the thing someone devised.
It's not just a thing, it's the reference for how to implement the thing.
If you have a recipe from 100 years ago that refers to ingredients and tools that are no longer available, or are now called something else, or need to be translated into current equivalents, those are all no problem.
But if the old recipe uses a term that we do still have, but means something different now than it did when written, that's a problem. Now you're breaking the very concept of writing and communicating and documenting. That's not a sane thing to do intentionally. Think scientific and industrial processes not just cakes.
In this particular case, since the feature happens to be presumed to be rarely used, it might be fairly easily addressed by just having the compiler issue a full stopping error for any use of auto by default, including the reason why so that the user doesn't just blindly add the flag to allow it.
In the future, when someone tries to build some code, it will fail to build, and that is 1000% prefferable to successfully building the wrong output.
auto v = MAX(a, b); where max infers the result type from the input types using generics or compiler intrinsics.
auto v = (struct foo){.a = 1}; where one wouldn’t want to repeat the type as in C++ auto v = make_unique<foo>(1);
struct foo v = (auto) {.a = 1 };I have a solution for that kind of thing: ./configure --maintainer.
If the building user identifies as a maintainer, then some things can happen differently. Stricter compiler options may be one. Another thing you might do in maintainer mode is update generated files (e.g. Yacc parsers) rather than using the canned, shipped code.
In TXR's ./configure, maintainer mode enables parallel make, which is suppressed otherwise. There is a way to enable it without requesting maintainer mode. Parallel make asks for problems because it can introduce race conditions into build steps, causing builds to intermittently fail. So in keeping with the theme of not breaking users, we disable it --- unless they announce themselves to be developing users via maintainer mode.
There is a worrying trend about -Werror, and that is that people turn it on and then when compilers add new warnings, builds fail and developers complain to the compiler developers. This is BAD. we should encourage compiler developers to find as many warnings as possible, and then users should turn off the once they don't like. Juste because a warning is stupid to you doesn't mean that it wont catch a bug for someone else. Compiler developers are responsible for correctly compiling your code, not to keep your code warning free.
I have spoken to several compiler developer who don't want to add new valid warnings because of the vitriol they will receive from developers.
That's a strange reply to a comment which specifically acknowledges the issue and describes one solution.
Not sure if this somehow changed at LWN because I thought I'd been able to look at this article before.
Returning the wrong data type has been an error with Clang since the earliest days. Why does GCC still allow that?
int main(void) {
struct {
int a;
} s;
return;
return &s;
return s;
}
$ gcc test.c
test.c: In function ‘main’:
test.c:5:3: warning: ‘return’ with no value, in function returning non-void
5 | return;
| ^~~~~~
test.c:1:5: note: declared here
1 | int main(void) {
| ^~~~
test.c:6:10: warning: returning ‘struct <anonymous> *’ from a function with return type ‘int’ makes integer from pointer without a cast [-Wint-conversion]
6 | return &s;
| ^~
test.c:7:10: error: incompatible types when returning type ‘struct <anonymous>’ but ‘int’ was expected
7 | return s;
| ^There is no keeping people happy.
GCC compiles C with a certain default dialect. It used to be gnu89 for the longest time, then gnu99 for a while. Now it is gnu11, if not higher. This default dialect is not ISO C; it's a GNU dialect.
So just to have your code processed as ISO C, you have to use a non-default option. Some GNU extensions are still recognized (rather than diagnosed as syntax errors) so if you wish not to accidentally use those, you need -pedantic also.
In Makefiles, you can tweak compiler options for individual files. E.g. with target-specific assignments in GNU Make.
# don't warn about conversions in old_parser.c
old_parser.o: CFLAGS += -Wno-conversionThe GCC implementation (and likely Clang also) supports altering diagnostics over sections of a translation unit.
void fun() { }
which is fully declared in C++, but in C it is an old-style function definition that doesn't declare anything about its arguments. void fun();
(which you typically find in a header file) indeed does not say anything about the function's arguments. You have to write void fun(void);
to specify that the function takes no arguments. For consistency, you can (and probably should) also use that style in the function's definition, but you don't have to.Anyway, C23 will align C's behavior with C++: void fun() will mean the same thing as void fun(void), whether as part of a function definition or not.
Does someone now a source of the 2nd Edition “ANSI C” with a good print quality? The ones sold by Amazon seem to be scans and no based on digital typesetting - which is mentioned in the first pages.
I suspect that plenty of people with the second edition on their bookshelves have retired already.
Well, they were playing with fire, and now are complaining.
I would love to help modernize these tools. Is the process to submit a merge request still based on mail lists? Can I just open a GitHub Pull Request somewhere if I decide to fix some package? Is there a list of packages that no one has picked up yet?
I'm sure you could get lots of people like me willing to help if you just made contributions a bit easier to make.