7 ms·
This is cool! I'm a pretty hardcore C programmer (been using it as my absolute main and favorite language for over 20 years), yet I find it hard to come up wit
by unwind 11y ago
This is cool!
I'm a pretty hardcore C programmer (been using it as my absolute main and favorite language for over 20 years), yet I find it hard to come up with some wishes for what I'd like to see.
Not sure how to interpret that, perhaps it's just indicative of a certain ... conservatism common in old people? :) Scary thought!
To be brutally concrete, I sometimes wish I could write someting like this:
do {
const bool flag = do_something();
...
...
} while(!flag);
That'd be very useful, but of course in current standards it's not possible since 'flag' isn't valid outside the scope it's declared in. So now we have to pre-declare 'flag' before the loop, breaking const-cleanliness too of course. This is obviously not a show-stopper, it's a minute thing. But it would be so nice! :)
Some support for automatic type inference would be nice, since most right-hand-side expressions have a type anyway it would be cool to be able to write
auto x = 3;
and have the type of 'x' be 'int' since that is the type of the literal '3'. Of course re-using "auto" like this would break their guiding principle, but it would look great (and, I think, somewhat mimic what C++ has done to that keyword).
Does anyone have some better ideas?
- alexhutcheson 11y agoFor your first case, why not: do { } while(!do_something()); Not trying to be snarky, I'd just like to understand :)
- mikeash 11y agoBecause it's often either like this: do { const bool flag = do_something(); do_something_else(); } while(!flag); Or like this: do { int whatever = get_some_data(); const bool flag = do_something(whatever); } while(!flag);
- p1esk 11y agoSomeone mentioned this instead: while (true) { const bool flag = do_something(); if (!flag) break; } Is it not what grandparent wanted?
- mikeash 11y agoYes, that would do it. It would just be nice to have it be better supported in the language rather than working around it like this. Any time you introduce break or continue into a loop you're making it more difficult to follow what's going on, since suddenly the exit condition can be anywhere. Not a big deal, especially if there's only one and it's right at the end, but mildly annoying that it can't be expressed more naturally.
- dalailambda 11y agoWhile some might claim this goes against the spirit of C, I think minor support for generics(enough to implement a type safe dynamic array e.g. vector) would be really useful. And if this did monomorphisation, then performance would still be great.
- adrusi 11y agoHow about just type parameters that let you implicitly get sizeof parameters and pass function pointers without having to unportably cast them.
- xioxox 11y agoWe already have C++, so is this required? If you want C with a dynamic vector, you could write C in C++ using std::vector.
- dalailambda 11y agoWhile it's important to not overload C with features, not adding features to it because C++ already has it isn't very practical.
- majewsky 11y agoIn these cases, I usually use while(true) with break, like while (true) { const bool flag = do_something(); if (!flag) break; }
- saisi 11y agoAuto's a great thought. It would really kill a class of numerical operations that lead to overflow with type mixing. On the other hand, I once had to get to terms with a code base with the most generous amount of autos. The class hierarchy was maybe was maybe 20 levels with an adequate amount of branching. At any point, I had no idea what particular object I was dealing with and always had to go follow a labyrinthine chain of predecessor function calls to determine the object type actually assigned to an object.
- ainar-g 11y agoOn auto. Couldn't they just define auto as _Auto and then add a header like <stdauto.h> which does #define auto _Auto like they did with _Bool in C99?
- jcranmer 11y agoauto is already a keyword in C11, a type of storage specifier (like static or register).
- PeCaN 11y agoYes, that's exactly why they'd use _Auto and a header to redefine the keyword. Existing code that does auto x = 3; (implicit int type) wouldn't break, but #include <stdauto.h> auto x = 4.2f; would be the new meaning.
- _kst_ 11y agoExisting code that does "auto x = 3;" is already broken; the "implicit int" rule was removed in C99. But "auto int x = 3;" is valid (and the "auto" keyword is useless in that context).
- jwilk 11y agoFrom <http://www.seebs.net/faqs/c-iaq.html#section-1 http://www.seebs.net/faqs/c-iaq.html#section-1>: 1.8: What's the auto keyword good for? Declaring vehicles.
- PeCaN 11y agoThis is inherited from early Lisp implementations, where it was common to define a struct car { ... }; which would get cumbersome to type.
- 21 11y agoIt seems the consensus is that new features like "auto" are not wanted: Principle 13: Unlike for C99, the consensus at the London meeting was that there should be no invention, without exception. Only those features that have a history and are in common use by a commercial implementation should be considered
- Peaker 11y agoBummer. Oh well, at least typeof and compound expressions can be blessed?
- cremno 11y agoDo you really consider it an invention? I think they mean inventions done by the committee (like <locale.h>). ISO C++ has this feature. And so does GNU C via the __auto_type keyword (GCC 4.9 and clang 3.8). History is there but I doubt it's commonly used (in C yet).
- pcwalton 11y agoWell, does implementation in C++ count? The wording is ambiguous.
- TorKlingberg 11y agoThis means that you should convince a compiler maker to add your innovation as a C extension. When it has been tested that way for a while, it may be added to the standard.
- colanderman 11y agoIf you're using GNU C: #define AUTO(var, def) __typeof__(def) var = (def) AUTO(x, 3);
- comex 11y agoOr, as of GCC 4.9 and Clang 3.8, just use __auto_type. It avoids duplicating the source expression, which duplicates compiler errors if the expression is erroneous and can actually repeat side effects in the rare cases involving variable-length arrays.
- PeCaN 11y agoI've only somewhat recently become a hardcore C programmer, but I actually quite like it. Wrote my own incremental generational garbage collector recently—the things you can do in C are fun. Here are some things I'd really like: Not language, rather standard library, but I would like to see a new allocation API with explicit control over alignment, separation of reserving and committing addresses, and generally updated for the fact that memory systems are different now than they were in 1979. aligned_alloc is alright, except there's no aligned_realloc. Linux always reserves addresses and doesn't commit until it needs to, but that can't be relied on for portable code. In short: we're in a 64-bit, virtual memory world. I don't want an allocator design from 1979. It's about time glibc's custom streams[1] get standardized. Real talk, it's 2016 and we can't define custom FILE * types. This doesn't even need to expose the libc's FILE implementation; it can remain opaque just fine. Language-wise, I'd like to see a pragma to covert an array of structs to a struct of arrays; i.e. declare #pragma struct SOA struct entity { uint32_t id; ... }; struct entity all_entities[1000]; and have the compiler rewrite it to struct { uint32_t id[1000]; ...[1000]; } all_entities; // where typeof(all_entites[N]) == typeof(struct entity) à la Jai[2]. This isn't a particularly hard transformation to do by hand, but it's kind of tedious. Standardizing M4 as a preprocessor would be a nice-to-have; i.e. you should be able to compile a .h.m4 or .c.m4 file directly. I don't know why GCC can't do this yet. It's a bit of a niche thing, but some of us are M4 addicts. C is in a pretty good place otherwise. I like to think there are 3 known local optima in terms of programming languages: C, Lisp, and Forth. All of them are a little hard at first, but quickly become very easy to think in. We'll probably never get any of this, which is a little depressing. I get the feeling the C committee doesn't really care that much about evolving the language any more. Modern, fast, safe(-ish), readable code is a GCC extension. 1. http://www.gnu.org/software/libc/manual/html_node/Custom-Streams.html#Custom-Streams http://www.gnu.org/software/libc/manual/html_node/Custom-Str... 2. https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md#data-oriented-structures https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md...
- Sanddancer 11y agoFor aligned_realloc, you may want to look at using jemalloc for your code, instead of the vendor malloc. It's got an "experimental" function rallocm that does allow you to choose the alignment. Regarding m4 as a preprocessor, I'd rather wishlist a proper macro system for Cx+n that could do the job of the preprocessor and any other uses of precompiling. The big problem with extending the C language is that C's in a ton of places. Some of the things you describe would mean increasing the size of the C runtime, which would be unacceptable in embedded programming and the like. Perhaps we need a middle ground language here -- more daring than C, more conservative than C++ -- where ideas can be tuned better and/or be specified for system types. C's universal assembly role really is a double edged sword as far as getting new stuff in the language.
- grok2 11y agoMy would-like-to-have in C is some equivalent of D's *Scope Guard" statement (https://dlang.org/spec/statement.html#ScopeGuardStatement https://dlang.org/spec/statement.html#ScopeGuardStatement) -- this will make error handling so much cleaner.
- naasking 11y ago> Does anyone have some better ideas? gcc's C extensions have some good ideas [1], particularly: 1. typeof(e) operator: great for use in macros 2. labels as values: used in just about every language interpeter 3. statement expressions: great for use in macros 4. fixed point types: who wants to hack their own fixed precision arithmetic? 5. vector extensions 6. arithmetic functions with overflow checking I think all of the above would make good additions to the C standard. [1] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
- kayamon 11y agoWell said. I'd like to see the gcc ".." operator for range-based switch cases and designated initializers become standardized.
- PeCaN 11y agoAs long as we keep __builtin_apply out of the standard, GCC is loaded with good ideas.
- naasking 11y agoYeah, after reading that I was really wondering about the use case for those extensions at the time they were added. I honestly can't think of any now.
- tropo 11y agoI'm not liking the fixed-point types. I'd rather see the ability to place an attribute on a floating-point variable that would inform the compiler that fixed-point might be suitable. You'd specify the requirements that need to be met, and the compiler would choose the fastest format for the current architecture. That format could be fixed-point, decimal float, IEEE float, or something weirder. For example, your requirements could include: minimum magnitude, maximum magnitude, minimum value, maximum value, maximum additive error, maximum multiplicative error, signed zero needed or not, NaN signed/unsupported/unsigned, infinity distinct from NaN and/or the largest number, etc. You say what you need for correctness, and the compiler makes it happen.
- dfrey 11y agoI think your do-while suggestion is kind of cool, but I think that this program may do different things under a current C compiler and one which includes the feature you suggested. int x = something(); do { const int x = somethingElse(); ... } while (x != 42);
- camgunz 11y agoSuper against auto. The type is implicit documemtation, and auto hides that. It probably also increases compile times.
- nanofortnight 11y agoIt doesn't increase compile times. The type information is already there for type checking.
- camgunz 11y agoSuper against auto. The type is implicit documemtation, and auto hides that. It probably also increases compile times.
- clevernickname 11y agoAll I want is Friendly C. Eliminate unnecessary sources of undefined behavior, stop exploiting undefined behavior in ways that breaks sensible code, and give me sane semantics like two's complement signed integers by default. http://blog.regehr.org/archives/1180 http://blog.regehr.org/archives/1180
- snthsnth 11y agoThings I'd like to see static lifetime compound literals. I don't see any reason not to be able to get the same effect as string literals for other types like: return (static int const []){1, 2, 3}; Disallowing branch-predicted values for relaxed atomic operations. I think c++ did this and it seems the sane way to go. Binary literals and binary printf format specifier. It would just occasionally be nice compared to hex. countof macro for arrays. I don't even care if it checked for non-array type errors, it would just be nice for it to be standard. Statement expressions and function literals would be nice, but I don't feel strongly about it.