discovery

Hello there,

the following program works, no matter how many times i repeat the semi colons.

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main() {

     int i = 3 ;;; ;;;;;;;; ;;;;;;; ; ;;;;;;;  ;;;;;;
     std::cout << i << std::endl;;;; ;;;  ; ;;

     return 0;
}


why is that ?
Semi-colon's just end a statement. There is nothing invalid about a statement that does nothing, it is likely to be filtered out by one component or another. I wonder how this would look in a debugger with optimization turned off though.
int i = 3 ;;;

is parsed as: <declaration statement> <expression statement 1> <expression statement 2>

<expression statement 1> and <expression statement 2> are null statements.

Expression statements have the form
expression-statement: expressionopt ;

The expression is a discarded-value expression. ... An expression statement with the expression missing is called a null statement. [Note: Most statements are expression statements — usually assignments or function calls. A null statement is useful to carry a label just before the } of a compound statement and to supply a null body to an iteration statement such as a while statement —end note]
Last edited on
@ JLBorges

thanks for replying, but i couldn't understand how it can be useful as it is mentioned in the paragraph you have quoted, would you mind simplifying that a bit ?
It's useful for doing things like this:
1
2
while (condition)
    ;

which is equivalent to
1
2
3
while (condition) {

}

which simply waits for condition to become true, and does nothing in the mean time. It's called busy-waiting, and it can be used to implement something called a spinlock among other things.
1
2
3
4
5
void copy( const char* srce_cstr, char* dest_cstr ) 
{
      // supply a null body to an iteration statement such as a while statement
      while( *dest_cstr++ = *srce_cstr++ ) ; // null statement
}


1
2
// busy idle: wait for a key to be entered
while( !kbhit() ) ; // #include <conio.h> (non-standard) 



1
2
3
4
// if( !( ( a == 4 ) || ( a == 6 ) || ( a == 7 ) || ( a == 22 ) ) ) do_something() ; // ugh!

if( ( a == 4 ) || ( a == 6 ) || ( a == 7 ) || ( a == 22 ) ) ; // do nothing
else do_something() ;


Wow, that's pretty cool !! thanks :)
but wait, my system monitoring application reports 100% CPU usage while the program is running !! is it efficient to use this in a real world application ?
It is only useful in... well, spinlocks tend to be used in OS development, so it is only efficient when the program doesn't wait long for a thread to open.
> my system monitoring application reports 100% CPU usage while the program is running !!
> is it efficient to use this in a real world application ?

No. Busy idle is rarely a good idea.

This would be less anti-social:
while( !kbhit() ) std::this_thread::sleep_for( std::chrono::milliseconds(100) ) ;
A real world use for this might be something like:

for(unsigned i = 0; i <= Number_Of_Custom_Classes_You_Want; Custom_Class_Default_Constructor()) ;

Although personally I don't like this for aesthetic reasons.
Last edited on
Topic archived. No new replies allowed.