why putting 2 semicolon is not an error? - c++

I just find out that no matter how many semicolons (if more than 0) the compiler will compile without error
#include <iostream>
int main()
{
int x;
x = 5;;
std::cout << x;;;
}
will just works fine, so why?

It's not an error because the language standard says so. It's OK to have empty statements, they do nothing, and are harmless.
There are times when it's useful:
#ifdef DEBUG
#include <iostream>
#define DEBUG_LOG(X) std::cout << X << std::endl;
#else
#define DEBUG_LOG(X)
#endif
int main()
{
DEBUG_LOG(1);
}
When DEBUG is not defined this will expand to:
int main()
{
;
}
If you couldn't have empty statements that would not compile.

The semicolon is a terminal, a token that terminates something. What exactly it terminates depends on the context.
For example, a semicolon character is at the end of the following parts of the C++ grammar (not necessarily a complete list):
an expression-statement
a do/while iteration-statement
the various jump-statements
the simple-declaration
Note that in an expression-statement, the expression is optional. That's why a 'run' of semicolons, ;;;;, is valid in many (but not all) places where a single one is.

A semicolon terminates a statement, consecutive semicolons represent no operation / empty statement.
No code will be generated for empty statement.

If you have two consecutive semicolons, there is an empty statement between them (just another way of saying: there is no statement between them). So, why are empty statements allowed?
Sometimes you need to use some construct, where the language expects a statement, but you dont want to supply one. For example, a common way to write a infinite loop is like this
for (;;) {
// do something
// ...and break somewhere
}
If c++ didnt allow empty statements, we would have to put some dummy statements instead of naked ;; just to make this work.

When you have ;;; in between you have empty statements. Remember C++ doesn't care about white space.

Related

Can you feed a macro to another macro as an argument, without the initial macro being expanded?

Background: My code, which I cannot post here will eventually run on a microcontroller, and the macros just offer a way to create multiple pin definition functions, via 1 single macro define mechanic. I use windows and gcc to experiment around with those.
I tried to abstract the problem as much as possible. I use the std console functions cause it is convenient for me to display it in the console window. As such, I also save the file as .cpp and compile it with g++ on windows.
Say I set up my code like this:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x) MACRO2(_x)
#define BAR 3
void fooBAR(int num)
{
std::cout << num << std::endl;
}
If I run the following code (working example)
int main()
{
MACRO2(BAR);
return 0;
}
first BAR gets inserted into ##_x and thus defines the function name which is to be called and then BAR gets inserted as the argument of that function and gets expanded to its value, so we get fooBAR(3). The code works, there are no errors.
Now if I try to add a macro in between (and this is the real world situation I am faced with for reasons I cannot go into), my code looks like this:
int main()
{
MACRO1(BAR);
return 0;
}
But this code throws an error, because when MACRO1(BAR) gets substituted with MACRO2(BAR), (BAR) then gets expanded into 3, and MACRO2(3) leads to foo3(3) which isn't defined, as confirmed by the error log:
error: 'foo3' was not declared in this scope
So the requirements are:
I need to pass BAR into MACRO1 and it needs to be passed to MACRO2 without being expanded
The word BAR has to stay exactly as it is, I know I could use ## in order to prevent it from expanding, but then I would need to add a char to BAR and the function call wouldn't work anymore.
Is it possible to somehow get this done? Pass a macro to another macro as an argument, without the initial macro being expanded in the process?
But this code throws an error, because when MACRO1(BAR) gets
substituted with MACRO2(BAR), (BAR) then gets expanded into 3, and
MACRO2(3) leads to foo3(3)
Yes. This is the specified preprocessor behavior for your particular set of macros.
After they are identified, the arguments to a function-like macro are fully macro-expanded before being substituted into the macro's replacement text, except where they are operands of the ## or # preprocessor operator. Any appearances of those operators are evaluated, and then the resulting text is rescanned, along with any following text as appropriate, for additional macros to expand.
Is it possible to somehow get this done? Pass a macro to another macro as an argument, without the initial macro being expanded in the process?
Only where the argument is the operand of a ## or # operator. The latter doesn't help you, but the former affords a workaround: you can pass an additional, empty argument so that you can perform a concatenation without changing the wanted argument:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x,dummy) MACRO2(_x##dummy)
#define BAR 3
int main()
{
MACRO1(BAR,);
return 0;
}
That expands to
int main()
{
fooBAR(3);
return 0;
}
If you want to avoid the extra comma, then you can do so by making MACRO1 variadic:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x,...) MACRO2(_x##__VA_ARGS__)
#define BAR 3
int main()
{
MACRO1(BAR);
return 0;
}
That expands to the same thing as the other.
Do note that both of these approaches afford the possibility of an error being introduced by providing unwanted extra argument values to the top-level macro. One would probably suppose that most such errors would be caught at compile time, as the expansion would result in broken code, like the attempt in the question. But it is hard to rule out the possibility that such an error would coincidentally expand to something that happened to be valid, but wrong.
One way to accomplish this is to change slightly the definition of BAR.
#define MACRO2(_x) foo##_x(_x())
#define MACRO1(_x) MACRO2(_x)
#define BAR() 3

C++ Addition within a Macro Function Argument

I have this snippet of C++ code from an exam. We are just suppose to write out what the output of the program is, I assumed the output would be '20', but the output is '10'. Why is this?
#define func(x) (x*x)-x
int i=3;
int main() {
cout << func(i+2) << endl;
}
If I put the i+2 in brackets like so:
cout << func( (i+2) ) << endl;
The output is '20' as assumed it would be.
How does C++ process this code that makes it return 10 not 20?
That's just how macros work. It's pure text substitution. So func(i+2) expands as:
(i+2*i+2)-i+2
which is to say:
2*i + 4
This is why typically macros would be written by excessively parenthesizing the arguments:
#define func(x) (((x)*(x))-(x))
But really, this is why you should strongly prefer functions to macros. While parenthesizing the arguments would fix the usage in func(i+2), it still wouldn't fix the usage in func(++i) - which while being a straightforward expression if func were a function is undefined behavior with the macro.
Because the brackets aren't there.
The macro expands to
(i+2*i+2)-i+2
And it all goes wrong from there. An inline function instead of a macro would just work.
Lessons to be learned: (1) Always parenthesise inside macro definitions. (2) DON'T USE MACROS IN C++!

Difference between block and in-line if statement

In C++ is there any difference in the assembly code generated by a statement such as:
if (*expr*) { }
vs.
if (*expr*) return;
Basically what I want to know is whether or not delimiting an if statement with brackets makes any difference to the underlying code generated than a simple return statement, as above.
If there's going to be only one statement within the block then both are identical.
if (e)
{
stmt;
}
if (e) stmt;
are the same. However, when you've more than one statement to be executed, it's mandatory to wrap them in {}.
No, there is no difference between the two examples. You can use a profiler to see what assembly code is outputted and see for your self.
Aside from the return statement, there is no difference.
A compiler may optimise out the first case altogether if the expression is either compile-time evaluable (e.g. sizeof) or has no side-effects.
Similarly, the second case might be optimised out to a simple return;
This function …
void f1(int e) {
if (e) {}
}
… compiles to …
f1:
rep ret
… while this function …
void f2(int e) {
if (e) return;
}
… compiles to …
f2:
rep ret
… when optimization is enabled using the -O2 option.
If there is only one statement, then there is no difference in using "block" and "writing inline".
Braces are used only to enclose a sequence of statements that are intended to be seen as a single process.
General syntax for if:
if ( condition_in_the_diamond )
statement_to_execute_if_condition_is_true;
So to make multiple lines of code as a single process, we use braces.
Hence if you have only one statement to execute in if statement, the it would be similar.
Using braces are better because it reduces the chances of error. Suppose you are commenting a line of code in hurry to debug:
if(condition)
// statement1;
statement2; //this will bring statement2 in if clause which was not intended
or while adding a line of code:
if(condition)
statement1;
statement3; // won't be included in if
statement2;
But if you are using inline statement as:
if(condition) statement1;
then it might prevent you from above error but it will make statement1 of limited length (assuming 80 character width code). That will make it sweet and simple to read though.
Hence unless you are using inline statement, using braces is suggested.
Source
With poorly-written macros nasty things can happen.
// c-style antipattern. Better use scoped_ptr
#define CLEANUPANDRETURN delete p; return
if (*expr*) CLEANUPANDRETURN;
// preprocesses to: (with added linebreaks)
if (*expr*)
delete p;
return;
Many functions of the C-Library may actually be macros. See
Why use apparently meaningless do-while and if-else statements in macros? for a trick of somehow safer macros.

C++ if Followed by a for Loop block

I remember once I've seen somebody writing C++ code like this:
if (something is true)
for (int i = 0; i < max; i++) {
//do something
line 1;
line 2;
line 3;
....
....
}
else
....
It works the same as the following code:
if (something is true) { //note the bracket here
for (int i = 0; i < max; i++) {
//do something
line 1;
line 2;
line 3;
....
....
}
}
else
....
I'm wondering if the compiler treated the for loop block as one line nested within the if clause? Can the multiple lines of code within bracket always be treated as one line? I can't quite understand how does the compiler parse and analyse this.
This is indeed correct code, although it may easily confuse readers. The if-statement considers the first following statement as it's then statement. Code between {} is usually considered a block or compound statement, containing the statements within it. Similarly, the for statement is considered one statement, including the loop body, which is the first statement to follow it (and can again be a block).
They are not really "lines" but rather statements. For instance your
line 1;
line 2;
line 3;
could be rewritten as and would be just as valid as:
line 1; line 2; line 3;
So the compiler is not really looking at lines but rather statements.
A single statement as defined by the grammar is considered either (somewhat simplified):
1) a simple statement terminated by a semicolon (as above)
OR
2) as a statement-block which is one or more simple statements enclosed within brackets {}.
Your first case runs fine because the if statement without brackets considers the next single statement(for loop)as a part of its body to be executed. The body of the for loop is a part of the loop itself.
If there had been no brackets for the loop itself, then only the first statement of the loop would have been executed.
{} defines a compound statement or block.
With the introduction of control structures we are going to have to
introduce a new concept: the compound-statement or block. A block is a
group of statements which are separated by semicolons (;) like all C++
statements, but grouped together in a block enclosed in braces: { }:
From cplusplus.com: Control Structures
The if control structure is defined as follows:
if (condition) statement
That statement can be defined as a single instruction/statement, or a compound statement. Either way, it's the next statement to be executed.
for (;;) statement is a special type of control structure called an iteration structure.
Therefore,
//The control structure is going to apply to the next statement
if (condition)
for (;;) //This for loop is the next statement. It applies to the next statement.
{
//The next statement is a compound statement.
}
Yes if there are no brackets after the if-statement it will just process the next line if the conditions are true. Since the next line was a for statement, it treats it as one command.

In C/C++ why does the do while(expression); need a semi colon?

My guess is it just made parsing easier, but I can't see exactly why.
So what does this have ...
do
{
some stuff
}
while(test);
more stuff
that's better than ...
do
{
some stuff
}
while(test)
more stuff
Because you're ending the statement. A statement ends either with a block (delimited by curly braces), or with a semicolon. "do this while this" is a single statement, and can't end with a block (because it ends with the "while"), so it needs a semicolon just like any other statement.
If you take a look at C++ grammar, you'll see that the iteration statements are defined as
while ( condition ) statement
for ( for-init-statement condition-opt ; expression-opt ) statement
do statement while ( expression ) ;
Note that only do-while statement has an ; at the end. So, the question is why the do-while is so different from the rest that it needs that extra ;.
Let's take a closer look: both for and regular while end with a statement. But do-while ends with a controlling expression enclosed in (). The presence of that enclosing () already allows the compiler to unambiguously find the end of the controlling expression: the outer closing ) designates where the expression ends and, therefore, where the entire do-while statement ends. In other words, the terminating ; is indeed redundant.
However, in practice that would mean that, for example, the following code
do
{
/* whatever */
} while (i + 2) * j > 0;
while valid from the grammar point of view, would really be parsed as
do
{
/* whatever */
} while (i + 2)
*j > 0;
This is formally sound, but it is not really intuitive. I'd guess that for such reasons it was decided to add a more explicit terminator to the do-while statement - a semicolon. Of course, per #Joe White's answer there are also considerations of plain and simple consistency: all ordinary (non-compound) statements in C end with a ;.
It's because while statements are valid within a do-while loop.
Consider the different behaviors if the semicolon weren't required:
int x = 10;
int y = 10;
do
while(x > 0)
x--;
while(x = y--);
While I don't know the answer, consistency seems like the best argument. Every statement group in C/C++ is either terminated by
A semicolon
A brace
Why create a construct which does neither?
Flow control statement consistency
Considering consistency...
if (expr) statement;
do statement; while (expr);
for (expr; expr; expr) statement;
while (expr) statement;
...all these flow-control constructs, end with a semicolon.
But, countering that we can note that of the block-statement forms, only do while is semicolon delimited:
if (expr) { ... }
do { ... } while (expr);
for (expr; expr; expr) { }
while (expr) { }
So, we have ';' or '}', but never a "bare" ')'.
Consistency of statement delimiters
We can at least say that every statement must be delimited by ; or }, and visually that helps us distinguish statements.
If no semicolon were required, consider:
do statement1; while (expr1) statement2; do ; while (expr2) statement3; while (expr3) statement4;
It's very difficult to visually resolve that to the distinct statements:
do statement1; while (expr1)
statement2;
do ; while (expr2)
statement3;
while (expr3) statement4;
By way of contrast, the following is more easily resolved as a ; immediately after a while condition tells you to seek backwards for the do, and that the next statement is unconnected to that while:
do statement1; while (expr1); statement2; do ; while (expr2); statement3; while (expr3) statement4;
Does it matter, given people indent their code to make the flow understandable? Yes, because:
people sometimes make mistakes (or have them transiently as the code's massaged) and if it visually stands out that means it will be fixed more easily, and
macro substitutions can throw together lots of statements on one line, and we occasionally need to visually verify the preprocessor output while troubleshooting or doing QA.
Implications to preprocessor use
It's also worth noting the famous preprocessor do-while idiom:
#define F(X) do { fn(X); } while (false)
This can be substituted as follows:
if (expr)
F(x);
else
x = 10;
...yields...
if (expr)
do ( fn(x); } while (false);
else
x = 10;
If the semicolon wasn't part of the do while statement, then the if statement would be interpreted as:
if (expr)
do-while-statement
; // empty statement
else
x = 10;
...and, because there are two statements after the if, it's considered complete, which leaves the else statement unmatched.
C is semicolon-terminated (whereas Pascal is semicolon-separated). It would be inconsistent to drop the semicolon there.
I, frankly, hate the reuse of the while for the do loop. I think repeat-until would have been less confusing. But it is what it is.
In C/C++ whitespace don't contribute to structure (like e.g. in python). In C/C++ statements must be terminated with a semicolon. This is allowed:
do
{
some stuff; more stuff; even more stuff;
}
while(test);
My answer is that, the compiler may get confusion, when we didn't include the semicolon in the termination of do.....while(); loop. Without this it is not clear about:
when the do ends?
If the while may a separate loop followed immediately after do loop.
That's why we include semicolon in the end of do......while loop, to indicate the loop is terminating here if the condition is false.