I wrote the absolute function using ternary operator as follows
int abs(int a) {
a >=0 ? return a : return -a;
}
I get the following error messages
../src/templates.cpp: In function ‘int abs(int)’:
../src/templates.cpp:4: error: expected primary-expression before ‘return’
../src/templates.cpp:4: error: expected ‘:’ before ‘return’
../src/templates.cpp:4: error: expected primary-expression before ‘return’
../src/templates.cpp:4: error: expected ‘;’ before ‘return’
../src/templates.cpp:4: error: expected primary-expression before ‘:’ token
../src/templates.cpp:4: error: expected ‘;’ before ‘:’ token
../src/templates.cpp:5: warning: no return statement in function returning non-void
If I write like this
return a>=0 ? a : -a;
I don't get any error.
What's the difference between the two?
The second and third arguments to the ternary operator are expressions, not statements.
return a
is a statement
Your syntax is incorrect.
It should be
if (a >=0)
return a;
else
return -a;
or the way you wanted it:
return a >=0 ? a : -a;
What's the difference between the two?
One is correct syntax, the other is not.
?: is an operator that takes three expressions and evaluates them in some way to produce a result. return a is not an expression (it's a statement), so your first form doesn't work. It's the same as you can't put return in the arguments of other operators: return a + return b will also not work.
If you want the returns in the separate branches, use if instead:
if (a >=0)
return a;
else
return -a;
Return is a statement and cannot be used where a value is expected.
You must use expressions (which usually yield a value) in the three components of the ternary operator.
Related
In C++, the following is valid and I can run it without a problem:
int main(){
if (int i=5)
std::cout << i << std::endl;
return 0;
}
However, even though the following should also be valid, it gives me an error:
if ((int i=5) == 5)
std::cout << i << std::endl;
Error:
test.cpp: In function ‘int main()’:
test.cpp:4:10: error: expected primary-expression before ‘int’
if ((int i=5) == 5)
^
test.cpp:4:10: error: expected ‘)’ before ‘int’
test.cpp:5:36: error: expected ‘)’ before ‘;’ token
std::cout << i << std::endl;
^
Furthermore, in C++17 the below code must be valid too, but it gives me a similar error again:
if (int i=5; i == 5)
std::cout << i << std::endl;
Error:
test.cpp: In function ‘int main()’:
test.cpp:4:16: error: expected ‘)’ before ‘;’ token
if (int i=5; i == 5)
^
test.cpp:4:18: error: ‘i’ was not declared in this scope
if (int i=5; i == 5)
^
I am trying to compile with g++ test.cpp -std=c++17. g++ --version gives me g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609. What am I missing here?
if ((int i=5) == 5) is a syntax error. It does not match any supported syntax for if statements. The syntax is init-statement(optional) condition, where condition could either be an expression, or a declaration with initializer. You can read more detail about the syntax on cppreference.
if (int i=5; i == 5) is correct. However, you are using an old version of GCC that dates from before C++17 was standardized. You would need to upgrade your compiler version. According to C++ Standards Support in GCC this feature was added in GCC 7.
For starters, I believe your compiler is right to reject
if ((int i=5) == 5)
because this is not legal C++ code. A variable declaration statement isn’t an expression, so you can’t treat (int i = 5) as an expression.
For the second one, I suspect you just need to update your compiler. g++ 5.6 is a fairly old version at this point, and I believe more updates versions of g++ will handle that code with no problem.
I'm compiling some C++ code that compiles fine for Android and iOS but fails under Linux. I've searched around and it looks like this kind of crash shows up when the implementer does something wrong; such as, using a reserved word. However I fail to see what I am doing wrong based on the error I'm getting.
In file included from external/rapidjson_artifact/include/rapidjson/document.h:20:0,
from src/main/cc/com/mycompany/serialization/JsonSerializer.h:4,
from bazel-out/k8-dbg/genfiles/src/main/java/com/mycompany/model/common/cc/com
/mycompany/model/common/Vector2d.h:13,
from bazel-out/k8-dbg/genfiles/src/main/java/com/mycompany/model/common/cc/com/mycompany/model/common/FastVector2d.h:10,
from src/main/cc/com/mycompany/api/gestures/primitives/CalculatedElementPosition.h:7,
from src/main/cc/com/mycompany/api/gestures/primitives/PointerInteraction.h:7,
from src/main/cc/com/mycompany/api/gestures/native/NativeUserInteractionHandler.h:10,
from src/main/cc/com/mycompany/linux/api/gestures/UserInteractionHandler.h:4,
from src/main/cc/com/mycompany/linux/api/opengl/OpenGlHandler.h:13,
from src/main/cc/com/mycompany/linux/api/opengl/OpenGlHandler.cc:1:
external/rapidjson_artifact/include/rapidjson/reader.h:189:15: error: expected unqualified-id before 'bool'
bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
^~~~
external/rapidjson_artifact/include/rapidjson/reader.h:189:15: error: expected ')' before 'bool'
In file included from /usr/include/GL/glx.h:30:0,
from src/main/cc/com/mycompany/linux/api/opengl/OpenGlHandler.h:7,
from src/main/cc/com/mycompany/linux/api/opengl/OpenGlHandler.cc:1:
external/rapidjson_artifact/include/rapidjson/reader.h: In member function 'void rapidjson::GenericReader<SourceEncoding, TargetEncoding, StackAllocator>::ParseTrue(InputStream&, Handler&)':
external/rapidjson_artifact/include/rapidjson/reader.h:623:26: error: expected unqualified-id before 'int'
if (!handler.Bool(true))
^
external/rapidjson_artifact/include/rapidjson/reader.h:623:26: error: expected ')' before 'int'
external/rapidjson_artifact/include/rapidjson/reader.h: In member function 'void rapidjson::GenericReader<SourceEncoding, TargetEncoding, StackAllocator>::ParseFalse(InputStream&, Handler&)':
external/rapidjson_artifact/include/rapidjson/reader.h:636:26: error: expected unqualified-id before 'int'
if (!handler.Bool(false))
^
external/rapidjson_artifact/include/rapidjson/reader.h:636:26: error: expected ')' before 'int'
external/rapidjson_artifact/include/rapidjson/document.h: In member function 'bool rapidjson::GenericValue<Encoding, Allocator>::Accept(Handler&) const':
external/rapidjson_artifact/include/rapidjson/document.h:1539:44: error: expected unqualified-id before 'int'
case kFalseType: return handler.Bool(false);
^
external/rapidjson_artifact/include/rapidjson/document.h:1539:44: error: expected ';' before 'int'
external/rapidjson_artifact/include/rapidjson/document.h:1540:44: error: expected unqualified-id before 'int'
case kTrueType: return handler.Bool(true);
^
external/rapidjson_artifact/include/rapidjson/document.h:1540:44: error: expected ';' before 'int'
In file included from src/main/cc/com/mycompany/serialization/JsonSerializer.h:4:0,
from bazel-out/k8-dbg/genfiles/src/main/java/com/mycompany/model/common/cc/com/mycompany/model/common/Vector2d.h:13,
from bazel-out/k8-dbg/genfiles/src/main/java/com/mycompany/model/common/cc/com/mycompany/model/common/FastVector2d.h:10,
from src/main/cc/com/mycompany/api/gestures/primitives/CalculatedElementPosition.h:7,
from src/main/cc/com/mycompany/api/gestures/primitives/PointerInteraction.h:7,
from src/main/cc/com/mycompany/api/gestures/native/NativeUserInteractionHandler.h:10,
from src/main/cc/com/mycompany/linux/api/gestures/UserInteractionHandler.h:4,
from src/main/cc/com/mycompany/linux/api/opengl/OpenGlHandler.h:13,
from src/main/cc/com/mycompany/linux/api/opengl/OpenGlHandler.cc:1:
external/rapidjson_artifact/include/rapidjson/document.h: At global scope:
external/rapidjson_artifact/include/rapidjson/document.h:2028:15: error: expected unqualified-id before 'bool'
bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
^~~~
external/rapidjson_artifact/include/rapidjson/document.h:2028:15: error: expected ')' before 'bool'
In file included from src/main/cc/com/mycompany/serialization/JsonSerializer.h:6:0,
from bazel-out/k8-dbg/genfiles/src/main/java/com/mycompany/model/common/cc/com/mycompany/model/common/Vector2d.h:13,
from bazel-out/k8-dbg/genfiles/src/main/java/com/mycompany/model/common/cc/com/mycompany/model/common/FastVector2d.h:10,
from src/main/cc/com/mycompany/api/gestures/primitives/CalculatedElementPosition.h:7,
from src/main/cc/com/mycompany/api/gestures/primitives/PointerInteraction.h:7,
from src/main/cc/com/mycompany/api/gestures/native/NativeUserInteractionHandler.h:10,
from src/main/cc/com/mycompany/linux/api/gestures/UserInteractionHandler.h:4,
from src/main/cc/com/mycompany/linux/api/opengl/OpenGlHandler.h:13,
from src/main/cc/com/mycompany/linux/api/opengl/OpenGlHandler.cc:1:
external/rapidjson_artifact/include/rapidjson/writer.h:109:15: error: expected unqualified-id before 'bool'
bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return WriteBool(b); }
^~~~
external/rapidjson_artifact/include/rapidjson/writer.h:109:15: error: expected ')' before 'bool'
All the errors point to rapidjson but I highly doubt that is the problem. It is probably something I'm doing wrong.
Can someone suggest what I should look for to find the root cause?
According to the accepted answer to a previous post
Declarations are not expressions. There are places where expressions
are allowed, but declararions are not. The left hand side of ?, the
trinary operator, is one of them.
Now, consider the following code segment:
#include <iostream>
using std::cout;
using std::endl;
enum struct status{invalid=0, valid};
status test (void);
int main (void){
status s = test();
cout << static_cast<int>(s) << endl;
return (0);
}
status test (void){
static auto invocation_count = 0;
++invocation_count;
//return (invocation_count % 2) ? (status::invalid) : (status::valid);
(invocation_count % 2) ? (return (status::invalid)) : (return (status::valid));
}
The function test() does not compile (note the compiler error log displays line numbers in the original test code):
g++ -ggdb -std=c++17 -Wall -Werror=pedantic -Wextra -c code.cpp
code.cpp: In function ‘status test()’:
code.cpp:19:31: error: expected primary-expression before ‘return’
(invocation_count % 2) ? (return (status::invalid)) : (return (status::valid));
^~~~~~
code.cpp:19:31: error: expected ‘)’ before ‘return’
code.cpp:19:83: error: expected ‘:’ before ‘;’ token
(invocation_count % 2) ? (return (status::invalid)) : (return (status::valid));
^
code.cpp:19:83: error: expected primary-expression before ‘;’ token
code.cpp:20:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
make: *** [makefile:20: code.o] Error 1
However, if the last line inside test(), which is the source of error, were to be commented out and the line above (presently commented out) were to be enabled, the code compiles.
Both the lines use the ternary operator for return switch, albeit differently. And in both cases, the left hand side of the ? inside the ternary operator does not include any declaration (in fact it is the same expression in both cases).
So why does one compile while the other doesn't?
This is a legal expression:
{expression} ? {expression} : {expression}
This is a legal statement:
return {expression};
So:
return (invocation_count % 2) ? (status::invalid) : (status::valid);
is:
return {expression} ? {expression} : {expression};
Which has the form:
return {expression};
That's perfectly legal.
On the other hand consider:
(invocation_count % 2) ? (return (status::invalid)) : (return (status::valid));
This has the form:
{expression} ? {statement} : {statement}
That is not legal because the ?: operator requires expressions before and after the colon.
Parts of ternary operator must be expressions. return is not an expression. It is a statement.
This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 8 years ago.
I have this strange (for me) behavior which I'm not able to explain and I wish to have your comments on this, please have a look at the following code:
void detach(callback_function_ptr const& ptr) {
observers.erase(remove_if(
observers.begin(),
observers.end(),
[&ptr](callback_function_ptr const& ptr2) {
return ptr.target<void(worker*)>() == ptr2.target<void(worker*)>();
}
));
}
When calling 'target' I need to specify which on I want to use, otherwise I get this compilation error:
test.cpp:47:44: error: no matching function for call to 'std::function<void(worker*)>::target() const'
And this is somehow understandable to me, I thought I may avoid to specify each time which 'target' function I want by preparing such a small 'helper':
template<typename T>
worker_ptr get_target(const function<T>& callback) {
return callback.target<T>();
}
Which looks a reasonable solution (to me :) ), but doesnt work:
test.cpp: In member function 'void (worker::* worker::get_target(const std::func
tion<T>&))(worker*)':
test.cpp:18:27: error: expected primary-expression before '>' token
return callback.target<T>();
^
test.cpp:18:29: error: expected primary-expression before ')' token
return callback.target<T>();
^
Well, here I don't catch the problem, why is not valid? Even if I use void(worker*) instead of T a compilation error is still present:
test.cpp:18:26: error: expected primary-expression before 'void'
return callback.target<void(worker*)>();
^
test.cpp:18:26: error: expected ';' before 'void'
test.cpp:18:26: error: expected primary-expression before 'void'
test.cpp:18:26: error: expected ';' before 'void'
I had used void(worker*) before in the 'detach' function with no problems, why here is not working? How does exactly behave the template type deduction and function call resolution in this case?
Thanks for your help
It should be (with extra template):
template<typename T>
worker_ptr get_target(const function<T>& callback)
{
return callback.template target<T>();
}
Hello there I am iplementingh a binary tree based on an underlying array.
My project is comprises a set of c++ files and the makefile for generating the compilation.
I am using g++ provided with DEV-C++ 4.9.9.2.
Upon launching compilation I get the following two set of errors.
AlberoBinariov.h: In member function bool AlberoBinariov<T>::figlioSinistroVuoto(typename Alberoa<T, int>::posizioneNodo)':
AlberoBinariov.h:198: error: expected)' before ';' token
AlberoBinariov.h:198: error: expected primary-expression before ')' token
AlberoBinariov.h:198: error: expected `;' before ')' token
AlberoBinariov.h: In member function bool AlberoBinariov<T>::figlioDestroVuoto(typename Alberoa<T, int>::posizioneNodo)':
AlberoBinariov.h:204: error: expected)' before ';' token
AlberoBinariov.h:204: error: expected )' before ';' token
AlberoBinariov.h:204: error: expected primary-expression before ')' token
AlberoBinariov.h:204: error: expected;' before ')' token
Interested portions of code are provided below:
template <class T>
bool AlberoBinariov<T>::figlioSinistroVuoto(posizioneNodo p)
{
return (figlioSinistro(p)==(posizioneNodo)P_NULL); //line 198
}
template <class T>
bool AlberoBinariov<T>::figlioDestroVuoto(posizioneNodo p)
{
return (figlioDestro(p)==((posizioneNodo)P_NULL)); //line 204
}
also for your convenince I have included the full source code at the link below.
https://filetea.me/t1sc3e60
Can you please let me know? thanks you in advance for your time. I look forward to hear from you.
Kind regards,
Gerald
PS: P_NULL is a NULL pointer constant declared in the Constants.h file.
You have 3 individual right parenthesis without their corresponding left parenthesis:
return (figlioDestro(p) == ((posizioneNodo)P_NULL)) /* -> */ )));
Change it to this:
return (figlioDestro(p) == ( (posizioneNodo)P_NULL ));