I'm trying to use the sequential evaluation operator (,
) in C, and I want to perform a for loop in the first expression, as below:
( for(initialization;condition;increment) foo() , bar() )
But writing that line I get an error: expected expression
.
I would not be surprised to find out this is an impossible thing to do, even though something making me dither is that I can perform a pseudo-if statement in the form of logical_expression ? expression_true : expression_false
.
Is there any way to do that? Or do I need to create the for loop externally?
EDIT:
I have decided to update my question to provide more context about my problem.
I have two functions, let's call them baz()
and qux()
. qux()
is the inverse function of baz()
, so for any given input, qux(baz(input))
should return the input.
Specifically, baz()
takes an array of chars, all of them between '0'
and '9'
, and returns a representation of that number in a different format that's not relevant to this question. When we pass that different representation to quz()
, we get back the original array.
So I want to build my own code to test an arbitrary number of cases and see if qux(baz(input))
is returning the desired result. And I want to do it in the least amount of lines of code possible (just putting all lines in the same one, separated by semicolons, is not what I'm looking for).
I know I could use a framework like CUnit to do it, but I want to do it on my own. And I know writing my code in this way makes it unreadable, and obfuscated, but I'd like to do it as a personal challenge. So I write (do not try to understand it, it is almost unreadable code):
#include "my_lib.h"
#include <stdlib.h>
#include <stdio.h>
int main() {
int i, errors_size = 0, str_size = 1;
char *str, **errors = NULL;
(str = malloc(sizeof(*str)*2) , str[0] = '1' , str[1] = '\0');
for( (i = 0) ; i < 10000 ; ( i++ , (str[str_size-1] == '9') ? ( ( str[str_size-2] == '9' ? str[str_size-1] = '0' , str_size++, str = realloc(str, sizeof(*str) * (str_size+1)), str[str_size- 1] = '0', str[str_size] = '\0' : str[str_size-2]++ , str[str_size-1] = '0' ) ) : ( str[str_size-1]++ ) ) ) ( printf("Trying %s:",str) , (strcmp(qux(baz(str)) , str) == 0) ? ( printf(" pass\n") , NULL ) : ( printf(" FAIL, got %s\n",qux(baz(str))) , errors_size++ , errors = realloc(errors, sizeof(*errors)*errors_size ) , errors[errors_size-1] = malloc( sizeof(*str)*(str_size+1) ) , memcpy(errors[errors_size-1] , str , sizeof(*str)*(str_size+1)) ) );
for ( ( printf("\n\nERROR SUMMARY:\n\nTried %d cases. %d errors found (%f%%)\n\n",i,errors_size,100.0*(((float)errors_size)/((float)i))) , i = 0 ) ; i < ( (errors_size < 100) ? errors_size : 1) ; i++ ) ( (errors_size < 100) ? (printf("%d.\t%s\t--> %s\n",i,errors[i],qux(baz(errors[i])))) : ( printf("The amount of cases to show is too big.\n") ) );
return 0; }
And that's only 7 lines of code, with the main part being executed in only two of it. I try to build a string of chars that begins at '1'
, and increment it for each step. However, when I reach numbers like 999, I have to set it all back to zeroes and add 1 at the beginning. And the only way I can think of to do that is using a for loop.
One possible solution would be creating a function to increment str
, but that would mean writing extra lines of code, which is not an optimal solution for my challenge.
The difference between a statement and an expression is covered by many good answer to this post. Wanted to highlight few alternatives that will achieve the equivalent of converting the for statement into an expression.
Some Notes:
This is not standard "C" - it's using GCC extensions.. You might have to enable those in the build, if the build ask for strict standard compliant.
The OP does not provide the specific case, so it's hard to tell if there are other specific alternatives
Option 1 - Statement as expression
See: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs
int func(void)
{
// Execute the loop as expression
({ for (...) foo() ; bar() }) ;
}
Option 2 - Using Nested Functions
See: https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html#Nested-Functions
int func(void)
{
void foo_loop(void) {
for (...) foo() ;
}
// Execute the loop as expression
( foo_loop(), bar() ) ;
}
The nested function foo_loop will have access to local variables.
Option 3 - Using a function call
It's not clear from the OP what are the loop dependencies. If it's is simple (e.g, loop N times), possible to use a helper functions
void foo_loop(int n) {
for (int i=0 ; i<n ; i++) foo() ;
}
int func(void)
{
// Execute the loop in the function
int n = 50 ;
( foo_loop(n), bar() ) ;
}