How many parameters does ios::setstate actually take? - c++

Every definition I've seen of function ios::setstate( iostate state ) shows that the function takes ONE and ONLY ONE parameter yet when I compile a program with the following function call, everything compiles and runs just fine:
mystream.setstate( std::ios_base::badbit, true );
What exactly is the second parameter and why is there no documentation about it?
EDIT: I'm using the command line compiler of the latest version of Microsoft Visual Studio 2010.

It's required to accept a single argument, as you've noted, but implementations are allowed to extend member functions via parameters with default values (§17.6.5.5). In other words, as long as this works:
mystream.setstate( std::ios_base::badbit );
your compiler is conforming. Nothing says that your code doesn't have to work, though.
(Your library implementation has decided that a boolean parameter would be useful to have. You never notice it because it has a default value, but you can still get into implementation-specific territory and provide the argument yourself. Whether or not this is a good idea is obviously another question, but probably not.)

Related

Is compiler allowed to call an immediate (consteval) function during runtime?

This might be a stupid question, but I am confused. I had a feeling that an immediate (consteval) function has to be executed during compile time and we simply cannot see its body in the binary.
This article clearly supports my feeling:
This has the implication that the [immediate] function is only seen at compile time. Symbols are not emitted for the function, you cannot take the address of such a function, and tools such as debuggers will not be able to show them. In this matter, immediate functions are similar to macros.
The similar strong claim might be found in Herb Sutter's publication:
Note that draft C++20 already contains part of the first round of reflection-related work to land in the standard: consteval functions that are guaranteed to run at compile time, which came from the reflection work and are designed specifically to be used to manipulate reflection information.
However, there is a number of evidences that are not so clear about this fact.
From cppreference:
consteval - specifies that a function is an immediate function, that is, every call to the function must produce a compile-time constant.
It does not mean it has to be called during compile time only.
From the P1073R3 proposal:
There is now general agreement that future language support for reflection should use constexpr functions, but since "reflection functions" typically have to be evaluated at compile time, they will in fact likely be immediate functions.
Seems like this means what I think, but still it is not clearly said. From the same proposal:
Sometimes, however, we want to express that a function should always produce a constant when called (directly or indirectly), and a non-constant result should produce an error.
Again, this does not mean the function has to be evaluated during compile time only.
From this answer:
your code must produce a compile time constant expression. But a compile time constant expression is not an observable property in the context where you used it, and there are no side effects to doing it at link or even run time! And under as-if there is nothing preventing that
Finally, there is a live demo, where consteval function is clearly called during runtime. However, I hope this is due to the fact consteval is not yet properly supported in clang and the behavior is actually incorrect, just like in Why does a consteval function allow undefined behavior?
To be more precise, I'd like to hear which of the following statements of the cited article are correct:
An immediate function is only seen at compile time (and cannot be evaluated at run time)
Symbols are not emitted for an immediate function
Tools such as debuggers will not be able to show an immediate function
To be more precise, I'd like to hear which of the following statements of the cited article are correct:
An immediate function is only seen at compile time (and cannot be evaluated at run time)
Symbols are not emitted for an immediate function
Tools such as debuggers will not be able to show an immediate function
Almost none of these are answers which the C++ standard can give. The standard doesn't define "symbols" or what tools can show. Almost all of these are dealer's choice as far as the standard is concerned.
Indeed, even the question of "compile time" vs. "run time" is something the standard doesn't deal with. The only question that concerns the standard is whether something is a constant expression. Invoking a constexpr function may produce a constant expression, depending on its parameters. Invoking a consteval function in a way which does not produce a constant expression is il-formed.
The one thing the standard does define is what gets "seen". Though it's not really about "compile time". There are a number of statements in C++20 that forbid most functions from dealing in pointers/references to immediate functions. For example, C++20 states in [expr.prim.id]/3:
An id-expression that denotes an immediate function shall appear only
as a subexpression of an immediate invocation, or
in an immediate function context.
So if you're not in an immediate function, or you're not using the name of an immediate function to call another immediate function (passing a pointer/reference to the function), then you cannot name an immediate function. And you can't get a pointer/reference to a function without naming it.
This and other statements in the spec (like pointers to immediate function not being valid results of constant expressions) essentially make it impossible for a pointer/reference to an immediate function to leak outside of constant expressions.
So statements about the visibility of immediate functions are correct, to some degree. Symbols can be emitted for immediate functions, but you cannot use immediate functions in a way that would prevent an implementation from discarding said symbols.
And that's basically the thing with consteval. It doesn't use standard language to enforce what must happen. It uses standard language to make it impossible to use the function in a way that will prevent these things from happening. So it's more reasonable to say:
You cannot use an immediate function in a way that would prevent the compiler from executing it at compile time.
You cannot use an immediate function in a way that would prevent the compiler from discarding symbols for it.
You cannot use an immediate function in a way that would force debuggers to be able to see them.
Quality of implementation is expected to take things from there.
It should also be noted that debugging builds are for... debugging. It would be entirely reasonable for advanced compiler tools to be able to debug code that generates constant expressions. So a debugger which could see immediate functions execute is an entirely desirable technology. This becomes moreso as compile-time code grows more complex.
The proposal mentions:
One consequence of this specification is that an immediate function never needs to be seen by a back end.
So it is definitely the intention of the proposal that calls are replaced by the constant. In other words, that the constant expression is evaluated during translation.
However, it does not say it is required that it is not seen by the backend. In fact, in another sentence of the proposal, it just says it is unlikely:
It also means that, unlike plain constexpr functions, consteval functions are unlikely to show up in symbolic debuggers.
More generally, we can re-state the question as:
Are compilers forced to evaluate constant expressions (everywhere; not just when they definitely need it)?
For instance, a compiler needs to evaluate a constant expression if it is the number of elements of an array, because it needs to statically determine the total size of the array.
However, a compiler may not need to evaluate other uses, and while any decent optimizing compiler will try to do so anyway, it does not mean it needs to.
Another interesting case to think about is an interpreter: while an interpreter still needs to evaluate some constant expressions, it may just do it lazily all the time, without performing any constant folding.
So, as far as I know, they aren't required, but I don't know the exact quotes we need from the standard to prove it (or otherwise). Perhaps it is a good follow-up question on its own, which would answer this one too.
For instance, in [expr.const]p1 there is a note that says they can, not that they are:
[Note: Constant expressions can be evaluated during translation. — end note]

Mark as deprecated function parameters in C++14

Reading this blog post and its comments, I have noticed that it gives as an example the possibility of marking specific function parameters as deprecated, as in (exaple taken from the post):
// Deprecate a function parameter
int triple([[deprecated]] int x);
Now I was wondering, what is a good use case for such a feature? No one in the comments of that post or anywhere else I have searched seem to have a clue.
EDIT:
To see it in action, there is a compilable example on goldbolt
Say you had a function like this:
void* allocate(std::size_t sz, void* hint = nullptr) {
// if you give `hint` it *might* be more efficient
}
And then you decided that it is no longer worth the effort to do stuff based on hint. So you would do this:
void* allocate(std::size_t sz, [[deprecated]] void* hint = nullptr) {
// `hint` is ignored. The compiler warns me if I use it in the
// function body accidentally, and people reading the function
// signature can see that it is probably going to be ignored.
}
This allows the library to keep the same signature/ABI (So you don't need to recompile stuff that uses it and legacy code can still keep using it without doing any harm), and also prevents it from accidentally being used again when changing the function.
But this is mostly for developers of the function, not the users of the function, in the future so they know why a seemingly "useless" parameter is there.
I would also think that this would disable the "unused parameter" warning with the -Werror=unused-parameter flag in gcc/clang, but it doesn't. Using (void) deprecated_parameter also issues a warning about using a deprecated parameter, so this seems like a bug. If it did disable the unused param warning, that would be another use case for [[deprecated]].
The rule is that the attribute is valid on, amongst other things, variable declarations (broadly). It's not specifically permitted for such declarations found in function arguments.
The original proposal, N3394, doesn't mention such a use case, either, and neither does the documentation for the original feature in GCC (which regardless accepts the equivalent usage) or in VS (I didn't check Clang).
As such, I think it's an "accident" that this is permitted, not something that anyone really had in mind as being useful.
Could it be useful to document deprecated defaulted arguments, as Artyer explores? Yes, potentially, and vaguely. But as Artyer also found, mainstream compilers don't actually react to this usage in a helpful manner.
So, at the present time, it's not useful, and the language feature wasn't particularly designed to be useful in this case.
Imagine a library that is implemented, used and maintained for many years. This library is used in multiple projects.
If you would simply remove the parameter, all the projects would have to immediately adapt the source code to be able to compile again, after they upgraded to the new library version.
If a default value is added to the parameter, but the parameter not used anymore, the projects would still compile without any change, but nobody would note that something has changed at all, and maybe some behaviour/feature that was controlled by this parameter does not work anymore.
So, by marking the parameter as deprecated the projects can compile without a change, but they get a warning that something has changed and that they should change their source code, because sooner or later this parameter will disappear.

Why can't constexpr just be the default?

constexpr permits expressions which can be evaluated at compile time to be ... evaluated at compile time.
Why is this keyword even necessary? Why not permit or require that compilers evaluate all expressions at compile time if possible?
The standard library has an uneven application of constexpr which causes a lot of inconvenience. Making constexpr the "default" would address that and likely improve a huge amount of existing code.
It already is permitted to evaluate side-effect-free computations at compile time, under the as-if rule.
What constexpr does is provide guarantees on what data-flow analysis a compliant compiler is required to do to detect1 compile-time-computable expressions, and also allow the programmer to express that intent so that they get a diagnostic if they accidentally do something that cannot be precomputed.
Making constexpr the default would eliminate that very useful diagnostic ability.
1 In general, requiring "evaluate all expressions at compile time if possible" is a non-starter, because detecting the "if possible" requires solving the Halting Problem, and computer scientists know that this is not possible in the general case. So instead a relaxation is used where the outputs are { "Computable at compile-time", "Not computable at compile-time or couldn't decide" }. And the ability of different compilers to decide would depend on how smart their test was, which would make this feature non-portable. constexpr defines the exact test to use. A smarter compiler can still pre-compute even more expressions than the Standard test dictates, but if they fail the test, they can't be marked constexpr.
Note: despite the below, I admit to liking the idea of making constexpr the default. But you asked why it wasn't already done, so to answer that I will simply elaborate on mattnewport's last comment:
Consider the situation today. You're trying to use some function from the standard library in a context that requires a constant expression. It's not marked as constexpr, so you get a compiler error. This seems dumb, since "clearly" the ONLY thing that needs to change for this to work is to add the word constexpr to the definition.
Now consider life in the alternate universe where we adopt your proposal. Your code now compiles, yay! Next year you decide you to add Windows support to whatever project you're working on. How hard can it be? You'll compile using Visual Studio for your Windows users and keep using gcc for everyone else, right?
But the first time you try to compile on Windows, you get a bunch of compiler errors: this function can't be used in a constant expression context. You look at the code of the function in question, and compare it to the version that ships with gcc. It turns out that they are slightly different, and that the version that ships with gcc meets the technical requirements for constexpr by sheer accident, and likewise the one that ships with Visual Studio does not meet those requirements, again by sheer accident. Now what?
No problem you say, I'll submit a bug report to Microsoft: this function should be fixed. They close your bug report: the standard never says this function must be usable in a constant expression, so we can implement however we want. So you submit a bug report to the gcc maintainers: why didn't you warn me I was using non-portable code? And they close it too: how were we supposed to know it's not portable? We can't keep track of how everyone else implements the standard library.
Now what? No one did anything really wrong. Not you, not the gcc folks, nor the Visual Studio folks. Yet you still end up with un-portable code and are not a happy camper at this point. All else being equal, a good language standard will try to make this situation as unlikely as possible.
And even though I used an example of different compilers, it could just as well happen when you try to upgrade to a newer version of the same compiler, or even try to compile with different settings. For example: the function contains an assert statement to ensure it's being called with valid arguments. If you compile with assertions disabled, the assertion "disappears" and the function meets the rules for constexpr; if you enable assertions, then it doesn't meet them. (This is less likely these days now that the rules for constexpr are very generous, but was a bigger issue under the C++11 rules. But in principle the point remains even today.)
Lastly we get to the admittedly minor issue of error messages. In today's world, if I try to do something like stick in a cout statement in constexpr function, I get a nice simple error right away. In your world, we would have the same situation that we have with templates, deep stack-traces all the way to the very bottom of the implementation of output streams. Not fatal, but surely annoying.
This is a year and a half late, but I still hope it helps.
As Ben Voigt points out, compilers are already allowed to evaluate anything at compile time under the as-if rule.
What constexpr also does is lay out clear rules for expressions that can be used in places where a compile time constant is required. That means I can write code like this and know it will be portable:
constexpr int square(int x) { return x * x; }
...
int a[square(4)] = {};
...
Without the keyword and clear rules in the standard I'm not sure how you could specify this portably and provide useful diagnostics on things the programmer intended to be constexpr but don't meet the requirements.

Why does wxMkDir return 0 when successfully creating a directory?

So, I have to admit upfront I already know the answer. I'm asking so others who happen to run into the same problem can find a solution to the problem caused by incorrect documentation.
My environment is VS 2015 C++, wxWidgets 3.0.2, developing on Windows 7.
In some legacy code, calls to wxMkDir were not being checked for success. According to wxWidgets documentation, wxMkDir has a return type of bool, and returns true if successful. However, it returns 0 when successful.
Why?
The answer is two-fold: there are two functions with similar names, wxMkdir and wxMkDir, with the former being documented and the latter not documented. The second part is that the seemingly valid presumption that they will behave the same is not a valid assumption.
The undocumented function wxMkDir maps to wxCRT_MkDir, which in turn maps to wxCRT_MkDirA, then to wxPOSIX_IDENT(mkdir), which creates a platform dependent name for the mentioned POSIX function, mkdir. According to the POSIX documentation for mkdir
Upon successful completion, mkdir() shall return 0. Otherwise, -1 shall be returned, no directory shall be created, and errno shall be set to indicate the error.
So, conditionals like:
if (!wxMkDir(newDir)) {
// handle the error here
}
will fail, but:
if (wxMkDir(newDir) != 0) {
// handle the error here
}
will work as anticipated based on whether the directory was created or not.
The documented function wxMkdir is implemented in wx source file filefn.cpp, and utilizes mkdir, but with conditionals like the above to map to the appropriate bool return value.
wxMkdir() and wxMkDir() are the unfortunate and ugly exceptions to the general rule that wxWidgets provides wxFoo() wrapper for all standard (meaning either ANSI C or POSIX as, in practice, the latter is about as standard and more so than C99) functions foo() existing in both narrow (char*) and wide (wchar_t*) versions.
So, according to this general rule, you'd expect wxMkdir() to behave as std::mkdir() but unfortunately wxMkdir() predated, by quite a few years, Unicode-ification of wxWidgets and so this rule couldn't be implemented for it because of backwards compatibility and another function had to be invented to be just a wrapper for std::mkdir().
And by now, of course, the weight of backwards compatibility is even heavier and there really doesn't seem to be anything reasonable to do here -- other than advising people to use wxFileName::Mkdir() which is unambiguous.
</sad-story>

What do the "..." mean in virtual void foo(...) = 0;?

Pretty simple question I think but I'm having trouble finding any discussion on it at all anywhere on the web. I've seen the triple-dot's as function parameters multiple times throughout the years and I've always just thought it meant "and whatever you would stick here." Until last night, when I decided to try to compile a function with them. To my surprise, it compiled without warnings or errors on MSVC2010. Or at least, it appeared to. I'm not really sure, so I figured I'd ask here.
They are va_args, or variable number of arguments. See for example The C book
Triple dots means the function is variadic (i.e. accepts a variable number of parameters). However to be used there should be at least a parameter... so having just "..." isn't an usable portable declaration.
Sometimes variadic function declarations are used in C++ template trickery just because of the resolution precedence of overloads (i.e. those functions are declared just to make a certain template instantiation to fail or succeed, the variadic function themselves are not implemented). This technique is named Substitution failure is not an error (SFINAE).
It's called ellipses - basically saying that function accepts any number of arguments of any non-class type.
It means that the types of arguments, and the number of them are unspecified. A concrete example with which you are probably familiar would be something like printf(char *, ...)
If you use printf, you can put whatever you like after the format string, and it is not enforced by the compiler.
e.g. printf("%s:%s",8), gets through the compiler just the same as if the "expected" arguments are provided printf("%s:%s", "stringA", "stringB").
Unless really necessary, it should be avoided, as it creates the potential for a run time error to occur, where it might otherwise have been picked up at compile time. If there is a finite, enumerable variation in the arguments your function can accept, then it is better to enumerate them by overloading.