Bumped into some code like this in our code base... which made me worried.
int foo(int a); // Forward declaration.
int baz() {
int result = {
int a = dosomestuff();
foo(a);
} ? 0 : -1;
return result;
}
Is the behavior of this code well-defined?
Will it really work, that result variable gets loaded with 0 or -1 depending on the return value of foo(a)?
For interest: The code was not written like that originally - however, it is what I imagine this innocent-looking macro will roll out to...
int foo(int a); // Forward declaration.
#define BAR() { int a = dosomestuff(); foo(a); }
int baz() {
int result = BAR() ? 0 : -1;
return result;
}
This is a GCC extension to C called 'statement expressions': http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
The key thing is that a statement expression returns the last thing it does as the value of the expression:
The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct.
In your example, that would be whatever foo(a) returns.
However the block must be enclosed in parens for GCC to accept the syntax.
int foo(); // Forward declaration.
int baz() {
int result = ({
int a = dosomestuff();
foo(a);
}) ? 0 : -1;
return result;
}
I'm unaware of any other compiler that supports this.
You'd have to consult your compiler documentation. This construct is not allowed in standard C or standard C++.
It's trivial to clean this up however, e.g.
int baz()
{
int result;
{
int a = dosomestuff();
result = foo(a)? 0: -1;
}
return result;
}
I do not know of a single compiler that will accept that. Additionally, you'd be better off doing this:
int foo();
int dosomestuff();
int baz()
{
int result = foo(dosomestuff()) ? 0 : -1;
return result;
}
It's not standard C++.
In standard C++, write
bool baz() { return !foo( dosomestuff() ); }
That's it.
Because it's a non-pointer simple type, the exact value will be returned and so the return behavior is defined. That block is... really strange though, and I'm surprised there's a C compiler that won't choke on it out there.
With C++11 you can get pretty close:
int foo(int a); // Forward declaration.
int baz() {
int result = []{
int a = dosomestuff();
return foo(a);
}() ? 0 : -1;
return result;
}
Related
It seems you can return an unnamed struct this way:
auto foo() {
struct {
int bar;
int square() {
return bar * bar;
}
} a { 7 };
return a;
}
Is there anyway to do this without the redundant variable name a, thus anonymously?
For starters C++ does not define anonymous structures. I think you mean an unnamed structure.
According ro the C++ Standard the return statement is defined like (8.6 Jump statements)
return expr-or-braced-init-listopt ;
So you may not use a declaration in the return statement. If so then you need prelimary to declare an object of the structure type that will be returned.
I have no idea what the point of this exercise is, so here is an answer that technically does what you ask for:
auto helper()
{
struct {
int x;
} a {0};
return a;
}
decltype(helper()) foo()
{
return {8};
}
https://godbolt.org/z/zA8C1V
The struct is unnamed.
foo does not return a named variable.
Of course this is straight up ridiculous - one would just name the struct instead of this decltype tomfoolery.
No, this is not possible.
The closest you can get is to use a functional-style cast to create a temporary, and use a C99-style scoped-initialiser; GCC allows this in C++ mode, as an extension:
#include <iostream>
#include <string>
auto foo() {
return (struct {
int bar;
int square() {
return bar * bar;
}
}) { 7 };
}
… but this is not portable (and will warn).
Without the braces around 7 the extension is not triggered, and you're back to standard code, in which it is illegal to define a type in a cast.
Instead of writing obtuse code, give your type a name and give your object a name. Your readers will thank you.
None of
struct {/*...*/} foo() { // Illegal
return {/*...*/};
}
auto foo() {
return struct { /*...*/ } { /*...*/ }; // Illegal
}
template <typename T = struct { /*...*/ }> // Illegal
T foo() {
return { /*...*/ };
}
are legal.
You have to, at least, have a named type, or a named instance.
Lambda allows to have neither, but you can only capture and define its operator():
auto foo() {
return [/*...*/](/*...*/) { /*...*/ }; // Legal
}
Returning anonymous struct
There is no such thing as anonymous struct in C++. That's enough to make it impossible.
There is a - limited - way of returning an object of anonymous type from a function: Returning a lambda.
auto make_square_function() {
return [bar = 7]() {
return bar * bar;
};
}
Lambdas are much more limited than general classes though. The members (captures) are encapsulated and cannot be named from the outside of the lambda and there are no member functions other than the function call overload.
Is there anyway to do this without the redundant variable name a
Only if you give the class a name:
struct Squarer {
int bar;
int square() {
return bar * bar;
}
};
auto foo() {
return Squarer{7};
}
Returning an instance of unnamed class is only possible by defining a variable.
Just for fun, another define-the-variable-in-another-function solution (taking inspiration from Max Langhof's answer)
auto foo ()
{
return []{ struct{int bar;} a {7}; return a; }();
}
No, because you need to return an instance of an object, in this case a.
The returned object has to exist somewhere in memory, you can't just return a class definition.
In your example, you don't return an anonymous struct, but you return an instance of that struct.
This code can't pass compiling. The only difference is the return type. Foo1's return type is the user-defined struct and Foo2's is int.
struct test
{
};
test Foo1()
{
return test();
}
int Foo2()
{
return 0;
}
int main()
{
test& r1 = Foo1(); //ok
int& r2 = Foo2(); //no but why? Is it the C++ standard way?
return 0;
}
It is either a compiler bug or its "language extension" (for example MS VC++ has many such "language extensions"). In both cases of the function calls the compiler shall issue an error because it may not bind a temporary object to non-const reference.
If you want to have a reference you can still use a reference to const otherwise neither of the line will compile :
struct test
{
};
test Foo1()
{
return test();
}
int Foo2()
{
return 0;
}
int main()
{
const test& r1 = Foo1(); // ok now
const int& r2 = Foo2(); //ok now
return 0;
}
This question already has answers here:
How to ensure constexpr function never called at runtime?
(5 answers)
Closed 1 year ago.
In C++11 we get constexpr:
constexpr int foo (int x) {
return x + 1;
}
Is it possible to make invocations of foo with a dynamic value of x a compile time error? That is, I want to create a foo such that one can only pass in constexpr arguments.
Replace it with a metafunction:
template <int x> struct foo { static constexpr int value = x + 1; };
Usage:
foo<12>::value
Unfortunately, there is no way guarantee that a constexpr function, even the most trivial one, will be evaluated by the compiler unless absolutely necessary. That is, unless it appears in a place where its value is required at compile time, e.g. in a template. In order to enforce the compiler to do the evaluation during compilation, you can do the following:
constexpr int foo_implementation (int x) {
return x + 1;
}
#define foo(x) std::integral_constant<int, foo_implementation(x)>::value
and then use foo in your code as usual
int f = foo(123);
The nice thing about this approach is that it guarantees compile-time evaluation, and you'll get a compilation error if you pass a run-time variable to foo:
int a = 2;
int f = foo(a); /* Error: invalid template argument for 'std::integral_constant',
expected compile-time constant expression */
The not so nice thing is that it requires a macro, but this seems currently inevitable if you want both guaranteed compile-time evaluation and pretty code. (I'd love to be proven wrong though!)
Yes, it can now be done in purely idiomatic C++, since C++20 added support for this kind of problem. You annotate a function with consteval and can be sure that it's being evaluated during compile time. https://en.cppreference.com/w/cpp/language/consteval
consteval int foo( int x ) {
return x + 1;
}
int main( int argc, char *argv[] )
{
return foo( argc ); // This will not compile
return foo( 1 ); // This works
}
Also see this godbolt.org demo in the 3 most relevant compilers.
I would use static_assert as shown in this example
#include<iostream>
constexpr int foo(int x) {
return x+1;
}
int main() {
// Works since its static
std::cout << foo(2) << std::endl;
static_assert(foo(2) || foo(2) == 0, "Not Static");
// Throws an compile error
int in = 3;
std::cout << foo(in) << std::endl;
static_assert(foo(in) || foo(in) == 0, "Not Static");
}
For more infos: http://en.cppreference.com/w/cpp/language/static_assert
I'm trying to do something like this in C++:
if(){
int a;
} else if(){
char a;
} else {
double a;
}
f(a);
But I get an error from the compiler saying that a was not declared in this scope.
I need to do a conditional declaration, how can I do it?
Many thanks
edit:
I cannot move the function inside the conditional as the problem is bigger:
f(a,b,c);
where a, b and c need to be declared in this way.
One way of doing what you seem to want is by defining a template function. You define the template and the compiler will compile versions of the function for each type you call it with.
template <typename T_my_type> T_my_type MyTemplateFunction(T_my_type a)
{
a++;
std::cout << a;
return a;
}
if(){
int a;
MyTemplateFunction(a);
} else if(){
char a;
MyTemplateFunction(a);
} else {
double a;
MyTemplateFunction(a);
}
In this case T_my_type is the template parameter and will be implicitly replaced with the type of the parameter that you call the function with.
Template programming in C++ is a rather large can of worms to open though, and as others have suggested, I think you may need to rethink your approach.
It appears that you want different overloads to be called depending on the path taken through the conditional structure. This is not possible in a static language like C++ because the compiler needs to decide which overload to call at compile time, and can only pick one for each call.
Do this instead:
if (...) {
int a = ...;
f(a);
} else if (...) {
char a = ...;
f(a);
} else {
double a = ...;
f(a);
}
C++ is a statically typed language. If you want to deal with a variable its type must be known at compile-time. If the conditions you want to check for are also known at compile-time there's probably a nice solution involving templates. If the expressions in your if statements are runtime dependent you have to move the function call inside the blocks that declare a.
you could use a union.
union my_type
{
int i;
char c;
double d;
}
my_type a;
if(){
a.i = ...;
} else if(){
a.c = ...;
} else {
a.d = ...;
}
f(a);
I don't know what f() will be doing, so I don't know if this will work in your situation. As someone else stated, templates are one option. Or you could try just type-casting instead of using a union.
Consider this instead:
union T
{
int i;
double d;
char c;
}
void process()
{
T t;
if(....) { work with t.i }
else if(....) { work with t.d }
else if(....) { work with t.c }
f(t);
}
void f(T t)
{
// now you have all your possible answers inside one variable
// you might need to send a 2nd flag to mark the actual type inside
// depending on your problem however, you might not need it
// work with t.i, t.d or t.c
}
If you must have f() on the outside and don't want to use unions, you can consider polymorphism:
class Base {};
class AInt : public Base { int a; };
class AChar : public Base { char a; };
class ADouble : public Base { double a; };
Base *p = NULL;
if(){
p = new AInt();
} else if(){
p = new AChar();
} else {
p = new ADouble();
}
f(a, b, c);
Ofcourse for this to have any real OOP quality you'll have to add some virtual methods to the Base class and implement them in the inheriting class to do the actual work you need be done or else you'll have this switch again somewhere inside f(), probing the real type of a.
You can also make f() as template function and implement the function for different data types.
f(template class T)
{
}
you can use boost library. For example
1. Boost::Any
boost::any a;
a=std::string("A string");
a=42;
a=3.1415;
f(a);
Link http://www.boost.org/doc/libs/1_40_0/doc/html/any.html
Boost::Variant
boost::variant a;
a=24;
a=2.52;
a="Fabulous!";
a=0;
f(a);
Link http://www.boost.org/doc/libs/1_40_0/doc/html/variant.html
If it possible, define macros for your conditions. In that way you can use this syntax
#if defined(CONDITION1)
int a;
f(a);
#elif defined(CONDITION2)
char a;
f(a);
#elif defined(CONDITION3)
double a;
f(a);
#endif
This is possible with a void pointer taking function. You would simply have to create a as a void* then have it point to one of your chosen variables. Then your function can simply handle which type it is. For example:
void *a;
int b;
char c;
double d;
char typeofa;
if(foo == 1){
a = &b;
typeofa = 0;
} else if(foo == 2){
a = &c;
typeofa = 1;
} else {
a = &d
typeofa = 2;
}
int bar(void* a, char typeofa)
{
//etc, do right thing dependant on typeofa
//casting a to right type then dereferencing
}
Note, I have not tested this code so it may contain minor syntax errors but demonstrates the principal.
Can a constructor call be evaluated to a boolean if the bool() operator is overloaded?
class A
{
public:
A() {};
operator bool() const { return true; }
}
main()
{
if (A a = A())
{
// do stuff
}
}
Is the above code valid, or do I need to implement main like:
int main(int argc, const char* argv[])
{
A a();
if (a)
{
// do stuff
}
}
This code is going to wind up all over the place in my code base, so less lines, increased legibility, and reduced scope are important, and would be improved by this.
Any ideas?
The code contains a few syntactic and semantic bugs. Let's fix them
class A
{
public:
A() {};
operator bool() { return true; }
};
int main()
{
if (A a = A())
{
// do stuff
}
}
You may choose to change the type in the conversion function to something else. As written, the boolean conversion will also succeed to convert to any integer type. Converting to void* will limit conversion to only bool and void*, which is a commonly used idiom. Yet another and better way is to convert to some private type, called safe bool idiom.
class A
{
private:
struct safe_bool { int true_; };
typedef int safe_bool::*safe_type;
public:
A() {};
operator safe_type() { return &safe_bool::true_; }
};
Back to syntax: If you have an else part, you may use the name of the declared variable, because it's still in scope. It's destroyed after all branches are processed successfully
if(A a = A())
{ ... }
else if(B b = a)
{ ... }
You may also use the same name as before, and the variable will shadow the other variables, but you may not declare the same name in the most outer block of any branch - it will conflict rather than hide with the other declaration.
if(int test = 0)
{ ... }
else
{ int test = 1; /* error! */ }
The technique to declare and initialize a variable is most often used together with dynamic_cast though, but can be perfectly used together with a user defined type like above, too
if(Derived *derived = dynamic_cast<Derived*>(base)) {
// do stuff
}
Note that syntactically, you have to initialize the variable (using the = expression form like for a default argument). The following is not valid
if(ifstream ifs("file.txt")) {
// invalid. Syntactic error
}
The answer to your first question is "yes", but your "constructor call" is wrong. A a declares a variable. It's a statement, not an expression. A() is an expression which constructs an anonymous temporary instance of A:
struct A
{
A() {};
operator bool() { return true; }
};
int main()
{
if (A())
{
// do stuff
}
}
If you want to use the instance of A in "stuff", then you need:
if (A a = A()) {
// do stuff
}
You can do this, but only when you're using the copy-initialization syntax to call your constructor. For example:
main()
{
if (A a = A())
{
// do stuff
}
}
Most compilers would elide the copy constructor in such an initializer when optimizations are enabled, but an accessible constructor is required nonetheless.
Also, naturally, if A would have a constructor such as A(int), you could also do this:
if (A a = 123) ...
Also, it is generally considered a bad idea to have operator bool() on your class for such purposes. The reason is that bool is in turn implicitly convertible to any numeric type (with false == 0 && true == 1); so, for example, the client of your class can write:
int x = A();
void foo(float y);
foo(A());
which is probably not something you want to allow. A simple trick is to use a pointer-to-member-of-private-class instead:
class A {
private:
struct dummy_t { int dummy; };
typedef int dummy_t::*unspecified_boolean_type;
public:
operator unspecified_boolean_type() const {
if (...) {
return &dummy_t::dummy; // true
} else {
return 0; // false
}
}
};
Pointers-to-members have an implicit bool conversion (as usual, null pointer is false, anything else is true), but they are not compatible with any type but their own; and, since the inner class here is private, no client code can possibly declare a variable of that type (auto and decltype in C++0x provide a way, though).
As a side note, main() as written is not valid C++ - ISO C++ does not have "default int" rule the way C does, and a function without an explicit return type is invalid.
If you're trying to indicate failure, why not throw an exception?
#include <stdexcept>
class Foo
{
public:
Foo(void)
{
if (/* something bad D: */)
{
throw std::runtime_error("Couldn't open file, etc...");
}
}
}
int main(void)
{
try
{
Foo f;
// do stuff with f
}
catch (std::exception& e)
{
std::cerr << "Error: " << e.what() << std::endl;
}
}