Is it possible to execute a "C" statement without a semicolon - c

Post an example to execute a "C" statement without semicolon( ; )

This line is a statement:
while (0) { }

You can an expression in an if() as long as it evaluates to a scalar (integer, floating point number or pointer).
if (expr, 0) {}
According to the C grammar, expr is an expression. if(expr){} is a selection_statement, so this would match the bill.
Note that the ,0 isn't always necessary since the body of the if() is empty. So these would be equivalent statements, if expr returns a scalar:
if (expr) {}
while (expr, 0) {}
while (expr && 0) {}
while (expr || 0) {}
All would evaluate the expression once.

Wrong answer
... with a new right answer below.
int main(void)
{
}
The pair of braces in the definition of main is a compound-statement which is one of the valid forms for a statement.
Edit: although a statement can be a compound-statement, and a function-body consists of a compound-statement, when the compound-statement is a function-body, it's not a statement.
Edit, Edit:
This program does contain a statement which is executed, though:
int main(void)
{
if (1) {}
}

Use this function:
__asm {
mov al, 2
mov dx, 0xD007
out dx, al
}

{ }
At least 15 characters are required to post an answer...

if (i=2) {} // give `i` a value

Even whole program (my GNU C built it despite result code returned is undefined).
The question is WHY?
/* NEVER DO THIS!!! */
int main()
{
{}
}
And in C++ we even can stabilize return code by this simple stack trick with variable
(yes, it is dirty, I understand but I think it should work for most cases):
/* NEVER RELY ON SUCH TRICKS */
int main()
{
if (int i=0) {}
}

int main()
{
// This executes a statement without a semicolon
if( int i = 10 )
{
// Call a function
if( Fibonacci(i) ) {}
}
// I have made my point
return 0;
}
int Fibonacci(int n)
{
return (n == 2) ? 1 : Fibonacci(n - 2) + Fibonacci(n - 1);
}

#define _ ;
int main()
{
return 0 _
}

Related

Using a for-loop in C to test the return value of a function

I'm pretty new to coding and especially to C, so I decided to take the CS50 course as an introduction to the language. I just finished watching the first lecture on C and, as a means to test my knowledge on the subject, I attempted to write a short little program. Also I am using the course's library for the get_int() function.
The goal is to test the user's input and check if it's less or equal to ten. If it matches the parameters, the program should print the "Success!" message and exit; otherwise, it should ask for input again. If the input value is over 10, the program responds just as expected, but if you input a value of 10 or less, it ends up asking you for input one more time before actually exiting. I think it's probably something with the "for" loop, but I just can't figure it out.
My code:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
int check_for_value();
int main()
{
for(check_for_value(); check_for_value() != 1; check_for_value())
{
printf("Failed!\n");
}
exit(0);
}
int check_for_value()
{
int i = get_int("Your value: \n");
if(i <= 10)
{
printf("Success!\n");
return 1;
}
else
{
printf("Try again!\n");
return 0;
}
}
That isn't doing exactly what you think it is. In your for loop, each time you write check_for_value(), it is going to call that function. So it will call it the first time and the return value will not matter. It will call it again for the middle statement and then the value will matter because you are comparing the output to not equal to 1. And then again it will call the function in the third statement, where again it won't matter. Usually for something like this, you would use a while loop instead. An example below:
int ret = check_for_value();
while(ret != 1) {
printf("Failed\n");
ret = check_for_value();
}
printf("Success\n");
Technically a for loop can work too as the following:
for(int ret = check_for_value(); ret != 1; ret = check_for_value()) {
printf("Failed\n");
}
The for loop can look very simply
for ( ; !check_for_value(); )
{
printf("Failed!\n");
}
In such a case it is better to use the while loop
while ( !check_for_value() )
{
printf("Failed!\n");
}
As for your for loop
for(check_for_value(); check_for_value() != 1; check_for_value())
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
then the underlined calls of the function are not tested.
Also bear in mind that such a definition of a for loop
for(int ret = check_for_value(); ret != 1; ret = check_for_value()) {
printf("Failed\n");
}
is a very bad style of programming. There is redundant records of the function calls. The intermediate variable ret is not used in the body of the loop. So its declaration is also redundant. Never use such a style of programming.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
and the statement
exit( 0 );
is redundant.

C, debugger breakpoints on simple if else statement

I'm very new to coding, I'm editing a simple C function in CodeBlocks. I'm getting a red error dot next to "else", I could't spot any problem with my code, perhaps its something I have overlooked. Please help, thanks!
int isZero (float f)
{
unsigned int u = *(unsigned int*)&f;
if ((u== 0x0) || (u==0x80000000) );
return 1;
else
return 0;
return (EXIT_SUCCESS);
}
Watch out for all semicolons. There's one more than you want.
You've got an extra semicolon there.
Remove the one from the end of if ((u== 0x0) || (u==0x80000000) );
The compiler reads the ; as a single statement doing nothing; and considers that the contents of the if block. The next statement is return 1;, which will always execute. When the compiler sees the else, it can't find the if that goes with it because that if block got closed with the first semicolon.
The compiler parses this as
int isZero (float f)
{
unsigned int u = *(unsigned int*)&f;
if ((u== 0x0) || (u==0x80000000)
/* do nothing */;
return 1;
else /* what does this go with? */
return 0;
return (EXIT_SUCCESS);
}
When you put a ; after an if clause it means that the if is an empty block.Therefore whether the statement is true or false the statement next to if is always excecuted.So your code
if ((u== 0x0) || (u==0x80000000) );
return 1;
evaluates to
if ((u== 0x0) || (u==0x80000000) )
{ //empty block
}
return 1; //always excecuted
Therefore the else part is never excecuted and the compiler does not see a if statement to relate this else to so you get an error.

Readable conditional logic without unnecessary execution?

I'm trying to make the below code both readable and performant. I want to avoid any unnecessary call to getFlagB() while also not repeating anything. Below I have written two methods, each which satisfies exactly one of these criteria.
Assume getFlagB() cannot be altered in any way. Is there a way to meet both these requirements simultaneously in C, without creating additional flags?
// Method 1 - doesn't repeat code blocks but calls getFlagB even when it may not need to
void foo(int flagA)
{
int flagB;
getFlagB(&flagB);
if(flagA & flagB)
{
// Code block 0
}
else
{
// Code block 1
}
}
// Method 2 - doesn't no extra call to getFlagB, but repeats code block 1
void foo(int flagA)
{
int flagB;
if(flagA)
{
getFlagB(&flagB);
if(flagB)
{
// Code block 0
}
else
{
// Code block 1
}
}
else
{
// Code block 1
}
}
You can do this:
void foo(int flagA)
{
int flagB;
if(flagA)
{
getFlagB(&flagB);
if(flagB)
{
// Code block 0
return ;
}
}
// code block 1
}
Wrap getFlagB() in another method, then let the compiler sort it out for you.
int myGetFlagB() { int b; getFlagB(&b); return b; }
void foo(int flagA)
{
/* note: assume you mean && and not &, otherwise there is no way
* to short circuit - you always need to call getFlagB for a
* bitwise AND.
*/
if(flagA && myGetFlagB())
{
// Code block 0
}
else
{
// Code block 1
}
}
Compute the condition explicitly before the if.
_Bool condition = flagA;
if ( flagA ) { /* First decide what to do. */
_Bool flagB;
GetFlagB( & flagB );
condition = flagA && flagB; /* Prefer && over &. */
}
if ( condition ) { /* Then do it. */
Code1();
} else {
Code2();
}
If you really do not want to either encapsulate the getFlagB call or split your if, you can abuse the comma operator:
if(flagA && (getFlagB(&flagB), flagB)) {
Even though it does not look nice, it does precisely what you want.
EDIT
You can also do the following, so long as flagB is initialized to 0. This avoids a bug in the code I posted earlier that assumes the flags aren't modified inside code block 0, which can cause both code blocks 0 and 1 to execute. I'd recommend this new one only because you may at some point want to modify the flags inside foo():
int flagB = 0;
if (flagA)
getFlagB(&flagB);
if (flagA && flagB) {
// code block 0
} else {
// code block 1
}
Yes, flagA is tested twice. You have a ternary condition, but you're asking for a binary set of outcomes. Without using sequence points as one person mentioned, you must test twice or duplicate code or unnecessarily call a function or add extra function call overhead if flagA happens to be set.
They're all valid solutions IMHO. It is just a matter of how readable and how well performing you want the code to be, not to mention avoiding code duplication... Nobody likes that! :-)
Happy coding!
I cannot definitively say anything because I have not seen any actual code but it seems to me the flagA is irrelevant and can be ignored. While flagB must be evaluated because it is relevant and causes the code to change.
void foo()
{
getFlagB(&flagB)
if(flagB)
{
//Code 1
}
else
{
//Code 0
}
}
But I am assuming that you do not have an unnecessary flag in your program. So I would recommend doing the seconded one it is more efficient and elegant even thought it does not seem that way.

return statement in macro(#define) in C

Is it possible to write a macro for the following function:
char *sent_same_text(char *txt)
{
return txt;
}
I tried
#define sent_same_text(txt) return(txt);
but getting compilation error.
Simply do:
#define sent_same_text(txt) (txt)
You only need return for functions. A macro is different in that it is a literal string insertion into your code. Make sure you have the parentheses around txt.
A return statement in a macro will return from the function that "calls" the macro. Function-like macros are shorthand for generating the same code multiple times. They are not actual function calls.
Here's an example of why you might put a return in a macro:
/* do-while() loop is a trick to let you define multi-statement macros and */
/* call them like functions. Note the lack of trailing ';' */
#define ERROR(msg) do{ fprintf(stderr, (msg)); errorCount++; return -1; }while(0)
/* foo() returns 0 or success or -1 on failure */
int foo(int x, int y){
if ( x < 10 )
{
ERROR("x is out of range\n");
}
if ( y < 20 )
{
ERROR("y is out of range\n");
}
doSomething(x,y);
return 0;
}
Calling foo with x = 25 would result in a return of -1, and the message "x is out of range" being printed.
Not saying that is good style, but hopefully illustrates how a return in a macro is different from a return in a function.
#define sent_same_text(text) (text)

Simulating conditionals

How can we code conditional behavior without using if or ? (ternary operator) ?
One idea comes to mind:
for(;boolean_expression;) {
// our code
break;
}
Any others ?
I hope what you dont want is just 'if' or 'ternary'.
#1
How about this:
Instead of : if (condition) printf("Hi");
Use:
condition && printf("Hi");
Short circuit evaluation. This is much similar to using if though.
#2
For if (condition) a(); else b();
Use:
int (*p[2])(void) = {b, a};
(p[!!condition])()
Using array of function pointers, and double negation.
#3
Yet another variant close to ternary operator (function, though)
ternary_fn(int cond, int trueVal, int falseVal){
int arr[2];
arr[!!cond] = falseVal;
arr[!cond] = trueVal;
return arr[0];
}
Use it like ret = ternary_fn(a>b, 5, 3) instead of ret = a > b ? 5 : 3;
switch(condition){
case TRUE:
ourcode();
break;
default:
somethingelse();
}
Using function pointers:
void ourcode(void){puts("Yes!");}
void somethingelse(void){puts("No!");}
void (*_if[])(void) = { somethingelse,ourcode };
int main(void){
_if[1==1]();
_if[1==0]();
return 0;
}
This relies on true boolean expressions evaluating to 1, which happens to be true for gcc, but I don't think it is guaranteed by the standard.

Resources