It's what you get when your C compilers are implemented in C++.
It's what you get when your C compilers are implemented in C++.
* nullptr: fixes problems with eg, va_arg
* better enums: Who doesn't want that? C is a systems language, dealing with stuff like file formats, no? So why shouldn't it be comfortable to define an enum of the right type?
* constexpr is good, an improvement on the macro hell some projects have
* unprototyped functions removed: FINALLY! That's a glaring source of security issues.
Really I don't see what's there to complain about, all good stuff.
It's called "change" and people don't like it.
nullptr is an overkill solution. The ambiguity could have been solved by mandating that NULL be defined as (void*)0 rather than giving implementations the choice of (void*)0 or 0.
Code written by C++ programmers.
Code written to be both C and C++.
>Although it would have been a bit of a pain to adapt,
>an '89 or '99 standard in which the only source representation
>of the null pointer was NULL or nil or some other built-in token
>would have had my approval.
https://groups.google.com/g/comp.std.c/c/fh4xKnWOQuo/m/IAaOe...
(Enumeration constants are the identifiers defined inside enum xxx {...})
If you look at CPPreference you can see how much complexity has been added to the C standard in the last few years.
In fact I don't see anything that needs support anywhere but the actual compiler.
-constexpr is not anything like constexpr in C++. -It makes no guarantees about anything being compile time. -It in no way reflects the ability of the compiler to make something compile time. -It adds implementation burden by forcing the implementations to issue errors that do not reflect any real information. (For instance you may get an error saying your constexpr isnt a constant expression, but if you remove the constexpr qualifier, then the compiler can happily solve it as a constant expression) -All kinds of floating point issues.
We should not have admitted this in to the standard, please do not use.
nullptr is the third definition of null. one should be enough, two was bad. why three?
Got any more information on that? Why does it fail in that way? Is that an implementation or a specification problem?
It fails for 2 reasons:
In order to make it easy to implement it had to be made so limited, that it in no way useful.
The second reason, and the real killer, is the "as if" rule. It states that any implementation can do what ever it wants, as long as the output of the application is the same. This means that how a compiler goes about implementing something is entirely up to the compiler. This means that any expression can be compile or execution time. You can even run the pre-processor at run time if you like! This enables all kinds of optimizations.
In reality, modern compilers like gcc, llvm and MSVC are far better at optimizing than what constexpr permits. However since the specification specifies exactly what can be in a constexpr, the implementations are required to issue an error if a constexpr does something beyond this.
> In order to make it easy to implement it had to be made so limited, that it in no way useful.
Such as?
> The second reason, and the real killer, is the "as if" rule.
Why is that a problem? It sounds like a benefit. It means that the optimization can't break anything, which to me is kind of the point.
Loops, function calls.... things available in C++
>Why is that a problem? It sounds like a benefit. It means that the optimization can't break anything, which to me is kind of the point
As-if is great! but the problem is that constexpr tricks people in to thinking that something is done at compile time, and the as-if rule overrides that and lets the implementation do it when ever it wants. constexpr is a feature over ridden by a fundamental rule of the language.
const int bla = 23;
const int blub[bla] = { 0 };
(see: https://www.godbolt.org/z/hjessMhGK)Isn't this exactly what constexpr is supposed to solve?
Maybe 'const' can't be fixed without breaking existing source code?
I don't really have a problem with adding a new keyword for 'actually const', maybe calling it 'constexpr' means C++ people have wrong expectations though, dunno.
For me, having constexpr being explicit about only accepting actual constant expressions, and creating an error otherwise (instead of silently falling back to a 'runtime expression') is fine, but the existing keyword 'const' has an entirely different meaning, there's just an unfortunate naming collision with other languages where const means 'compile time constant'.
A lot of these ARE relevant and useful improvements to the C language itself; constexpr reduces the need for macro-constants (which is nice), ability to specify the enum storage type is often helpful and clean keywords for static_assert etc. are a good idea too.
And getting rid of the "void" for function arguments is basically the best thing since sliced bread.
const is sufficient to eliminate the use of macro-constants with the exception of the use of such constants by the preprocessor itself (in which case constexpr is also inapplicable).
#define DEF (ABC+(GHI<<JKL_SHIFT))I hope for your sake that you don't speak this way other than anonymously on the Internet; it reflects very poorly of you.
Also it can (in my opinion, brains seems to work differently) lower the cognitive load of a piece of code, by simply reducing the clutter.
Sure it can obscure the exact type of things, but I guess that's the trade-off some people are willing to do, at least sometimes.
Something like:
const auto got = ftell(fp);
saves you from having to remember if ftell() returns int, long, long long, size_t, ssize_t, off_t or whatever and in many cases you can still use the value returned by e.g. comparing it to other values and so on without needing to know the exact type.If you want to do I/O (print the number) then you have to know or convert to a known type of course.
This was just a quick response off the top of my head, I haven't actually used GCC 13/C2x yet although it would be dreamy to get a chance to port some old project over.
No no no no nonononono. No!
Loose typing was a mistake. I think any sober analyst of C and C++ knows that. The languages have been trying to rectify it ever since.
But dynamic typing was an even bigger mistake. Perversely, it's one caused by a language not having a compiler that can type check the code, which C does.
I want to actually know what my code is doing, thanks. If you want "expressive" programs that are impossible to reason about, just build the whole thing in Python or JS. (And then pull the classic move of breaking out mypy or TypeScript half way in to development, tee hee.)
The only time `auto` is acceptable is when used for lambdas or things whose type is already deducable from the initializer, like `auto p = make_unique<Foo>()`.
In this case it would be long. I fail to see the huge risk you're implying by operating upon a long-typed value without repeating the type name in the code.
const auto pos_auto = ftell(fp);
const long pos_long = ftell(fp);
I don't understand what you can do with 'pos_long' that would be dangerous doing with 'pos_auto' (again, disregarding I/O since then you typically have to know or cast).Thank you for answering for me!
That's one reason type inference is safer than not inferring. Your program doesn't include semantics you didn't actually intend to be part of its meaning.
Also, I think lambdas would be annoying without it.
I meant that, to a person reading the code, `auto` tells you about as much about the type you're looking at as no type at all (like in a dynamically typed language).
This chatter said it better: https://news.ycombinator.com/item?id=35814337
#noauto
std::unordered_multimap<string, std::unordered_multimap<string, someclass>> getWidgets();
With templates you can easily have very unwieldy types, and there's not that much benefit from spelling them out explicitly.Like any tool, there are good and bad uses of it. Well used, it removes unnecessary clutter and makes the code more readable.
But I'm not a big fan either.
#define MAX(A, B) ({ auto a = (A); auto b = (B); a>b? a : b; })
As-is, for such things I just use __auto_type, as it's already in the GNU-extension-land.How many of you guys have half of a C compiler lying around in a directory somewhere on your machines?
(And how do you find the time for WG14 AND writing code AND doing research? My cousin is in roughly the same field as you and you publish more than he does.)
Use size_t
https://thephd.dev/c23-is-coming-here-is-what-is-on-the-menu...
(TL;DR: it makes sense in macros)