if and else without braces - c++

I expect the following code to compile. Clang and VC++ both give me an error on the line with else.
void MyFunction(std::int32_t& error)
{
std::int32_t variable = 0;
if(GetSomething())
error = EOK;
else
error = ERROR;
}
If I put curly braces around error = EOK;, then it compiles. Why does VC++ say:
illegal else without matching if
?
My full code is below, replacing std::uint32_t with a typedef. It still gives the same error in VC++.
using sint32 = int;
#define ERROR 5;
#define EOK 0;
bool GetSomething();
void MyFunction(sint32& error)
{
sint32 variable = 0;
if (GetSomething())
error = EOK;
else
error = ERROR;
}

If your definition of EOK is as follows:
#define EOK 0;
then it would cause this type of error, because it forcibly terminates the if-statement before the else is reached, making it an else without a matching if. The compiler sees this code after macro replacement:
if(GetSomething())
error = 0;;
else

Here is a possible fix:
enum
{
EOK = 0,
ERROR = 5
};
Note that all identifiers starting with E followed by either another uppercase letter or a number are reserved for use as macro names by <cerrno>, so to avoid name clashes consider using a different naming convention for your errors.

To be implest and more efficient, you can do :
error = (GetSomething()) ? 0 : 5 ;
And if you want to with enum as Matt say , it become :
error = (GetSomething()) ? enum.EOK : enum.ERROR ;

Related

why my code is giving undeclared variable error?

include "stdafx.h"
#include <vector>
#include <iostream>
std::vector<int> biggest;
std::vector<int>vector1;
std::vector<int>vector2;
int main(){
biggest = [vector2[0],0]; //wrong initialization
for (int apply = 0; apply < (vector2.size()); apply++) {
if (biggest[0] < vector2[apply + 1]) {
biggest[0] = vector2[apply + 1];
biggest[1] = apply + 1;
}
}
Error C2065 'apply': undeclared identifier.why this error is occurring as i have already defined apply variable in for loop. error should be in initialization of biggest(vector).why wrong compiler code?
even intellisense is not giving me error is it a visual studio bug?
apply is in scope in the for loop body, so be assured, the error is not there. But you are aware that apply is out of scope after the loop body?
I'm only answering this because your use of
vector2.size() - 1
will give you hell if vector2 is empty, as the above will wrap around to a large unsigned value and your program will fail spectacularly! Use
for (int apply=0; apply + 1 < vector2.size(); apply++) {
instead.

rewrite define macro as c++ code?

How i can write this macro as c++ code?
extern bool distribution_test_server;
bool distribution_test_server = false;
#define GetGoldMultipler() (distribution_test_server ? 3 : 1)
And one more question, what is the vale of the macros if distribution_test_server = false;
Soo if distribution_test_server is false... then the macro it's not used?
Example i have this :
#define GetGoldMultipler() (distribution_test_server ? 3 : 1)
You can write it as an inline function:
inline int GetGoldMultipler()
{
return distribution_test_server ? 3 : 1;
}
If distribution_test_server is false, the multiplier returned is 1.
It's already C++ code, but I assume you want to rewrite it as a function:
int GetGoldMultiplier() {return distribution_test_server ? 3 : 1;}
If distribution_test_server is false then the gold multiplier will be 1; that's how ?: works. (If the first part is true, the second part is returned; else the third part)
What is defined in this macro is what we call a ternary expression.
It's basically an "if" condition concatenated, this expression can be resumed as :
int MyFunction()
{
if(ditribution_test_server == true)
{
return 3;
}
else
{
return 1;
}
}
more on ternary conditions : http://www.cprogramming.com/reference/operators/ternary-operator.html
Now the macro is something completely different. When you define a macro and use it in your code, the compiler replace the macro by what you wrote on the right side.
For example :
#define MY_MACRO 8
int a = MY_MACRO;
actually translate to:
int a = 8;
more on macros : http://www.cplusplus.com/doc/tutorial/preprocessor/
So in your code #define GetGoldMultiplier() (distribution_test_server ? 3 : 1) defines a macro named GetGoldMultiplier() (which is NOT a function !) which upon use will be replaced by (distribution_test_server ? 3 : 1) which can be interpreted as what I wrote before.
The macro will replace any place it you code where there is the symbol GetGoldMultiplier() with the expression "distribution_test_server ? 3 : 1" And this happens as a precompilation step so before the code is interpreted. This also means that there never will be a function GetColdMultiplier() even if your code looks like it is calling it.
This means that if distribution_test_server is false then the expression will always be 1. if it is true the value will always be 3.
That is because the expression
val = a ? 3 : 1
is a short hand syntax inherited from C for the code
if (a)
{
val = 3;
}
else
{
val = 1;
}
You could so of achieve the same thing with an inline function but inline is only a compiler suggestion the macro is guaranteed to do this. But if inlining is preformed, then the result will be equivalent.
inline int GetGoldMultipler()
{
return distribution_test_server ? 3 : 1;
}

Can't find my mistake! error: expected identifier before '(' token

This is my main code, I did search related mistakes before asking but it just doesn't seem wrong...The IDE says the error is in line 11.
#include<stdio.h>
int main()
{
float sal;
printf("Digite o salário bruto: ");
scanf("%f",&sal);
if(sal<=2246.75){
printf("Salário líquido : ",sal);
}
else{
if(sal>2246.75)&&(sal<2995.70){
printf("Salário Líquido: ",sal * 0.925);
}
else{
if(sal>2995.70)&&(sal<=3743.19){
printf("Salário Líquido: ",sal * 0.845);
}
else{
printf("Salário Líquido: ", sal * 0.775);
return 0;
}
}
}
}
if(sal>2246.75)&&(sal<2995.70){
The problem is that the entire condition must be placed within a set of parentheses.
It's fine if you want to further enclose the sub-conditions, but you must surround the entire lot, too:
if ((sal > 2246.75) && (sal < 2995.70)) {
Your if statement has to correct as follows, here you were missing bracket() for if.
if( (sal>2246.75)&& (sal<2995.70)){
You have to specify the formatter for printf correctly as follows; here you are missing type formatter.
printf("Salário Líquido: %f", sal * 0.775);
Both these errors are there in multiple occasions in your code.
there are actually two major kinds of problems with the posted code.
printf("Salário líquido : ",sal);
is missing a format specifier for the 'sal' variable
it should be:
printf("Salario liquido : %f", sal);
Note: each of the printf() statements have this same problem
if(sal>2246.75)&&(sal<2995.70){
is missing the outside parens
it should be:
if( (sal>2246.75) && (sal<2995.70) ) {
Note: I added some horizontal spacing for clarity only
the last two 'if' statements have this same problem
Suggest compiling with all warnings enabled.
For gcc, at a minimum, use '-Wall -Wextra -pedantic'
main always returns an 'int'
To avoid that return code being a random value, always end the function with:
return(0);
I think that if(sal>2246.75)&&(sal<2995.70) is supposed to be
if(sal>2246.75 && sal<2995.70).

Invalid use of auto

In this code:
for ( ;(auto i = std::find(some_string.begin(),some_string.end(),'%')) != some_string.end();)
{
}
I'm getting error from gcc 4.7.1:
error: invalid use of 'auto'|
any ideas why? shouldn't that be correctly compiled?
I think it has nothing to do with auto. You just cannot declare variables in random places, for example this will not compile either - an equivalent of what you were trying to do, but without auto:
int main() {
for ( ; (int i = 0) != 1; ++i)
;
return 0;
}
If this is in a loop, you'll only ever find the first '%'. You need to resume searching from i, not some_string.begin() to find subsequent '%'.
auto i = std::find(some_string.begin(), some_string.end(), '%'));
while (i != some_string.end()) {
// Your code here.
i = std::find(i, some_string.end(), '%')); // Find next '%'.
}

Assigning and Conditional Testing Simultaneously in C++

I have three functions that return integer error codes, e.g.
int my_function_1(const int my_int_param);
int my_function_2(const int my_int_param);
int my_function_3(const int my_int_param);
I want to assign and test for error at the same time for brevity. Will the following work and be portable?
int error=0;
...
if ( error ||
(error = my_function_1(val1) ||
error = my_function_2(val2) ||
error = my_function_3(val3)) ) {
std::cout << "AN ERROR OCCURRED!!!" << std::endl;
}
Thanks!
Why not throw an exception?
void my_function_1(const int my_int_param);
void my_function_2(const int my_int_param);
void my_function_3(const int my_int_param);
try {
my_function_1(...);
my_function_2(...);
my_function_3(...);
} catch(std::exception& e) {
std::cout << "An error occurred! It is " << e.what() << "\n";
}
I don't understand why you have the error && at the beginning of the function, but the rest should do what you want. Short circuit evaluation of the || operators is guaranteed by the standard. I would consider it bad style though.
Edit: Based on your comment, you would need to replace error && with error ||. I will also add that this is a good reason to use exceptions rather than error codes, it makes your code so much easier to read.
error is initialized to 0.So the && will always evaluates to false. So other parts of the if condition are never evaluated. So this code will not work. If you remove the && condition the code should work portably as the standard guarantees the order of the evaluation in this case.
Yes, after the minor change of && with || it will work. But it's just too confusing (using = in tests is confusing) with not much benefit.
You could go for exception line another poster suggested, or simply put your checked code inside function and do like below.
int checked(){
int error = 0;
error = my_function_1(val1); if (error) return error;
error = my_function_2(val1); if (error) return error;
error = my_function_3(val1); if (error) return error;
return error;
}
I believe any programmer will easily understand what is done here.