-2

Something like

int main(void){
    doTenTimes({
        printf("Hello World");
    });
}

And then the function doTenTimes could execute that block of code 10 times.

Julian M
  • 1
  • 2
  • 1
    You can not pass a code block because code block does not have a type. You may pass only objects of complete types. – Vlad from Moscow Jan 21 '22 at 13:32
  • Are you aware of function pointers? – user694733 Jan 21 '22 at 13:33
  • [How do function pointers in C work?](https://stackoverflow.com/q/840501/327083) – J... Jan 21 '22 at 13:36
  • If you compile with Clang, you can do it using the blocks extension: `#include ` / `void doTenTimes(void (^block)(void)) { for (int i = 0; i < 10; ++i) block(); } int main(void) { doTenTimes( ^{ printf("Hello World.\n"); } ); }`. – Eric Postpischil Jan 21 '22 at 13:51
  • What you really want here is a [lambda](https://en.wikipedia.org/wiki/Lambda_(programming)), and C doesn't have them. – Steve Summit Jan 21 '22 at 14:10

3 Answers3

0

You probably don't want to "pass a block of code", but rather to implement the function to suit whatever you need to do:

void doManyTimes(int n)
{
  for(int i=0; i<n; i++)
    printf("Hello World\n");
}

Alternatively, you could pass a function pointer pointing at a different function, to provide the behavior separately:

typedef void dofunc_t (void);

void print (void)
{
  printf("Hello World\n");
}

void doManyTimes(dofunc_t* func, int n)
{
  for(int i=0; i<n; i++)
    func();
}

// call:
doManyTimes(print,10);
Lundin
  • 195,001
  • 40
  • 254
  • 396
0

You really can't treat "naked" blocks of code like data in C. Lundin's approach is the best for what you want to do.

However, for completeness' sake, here's an example using a macro (FOR THE LOVE OF GOD NEVER DO THIS):

#include <stdio.h>

/**
 * Wrapping in a do...while(0) keeps the compiler from bitching at
 * me over the trailing semicolon when I invoke the macro in main.
 */
#define doTenTimes(STMT) do { for (size_t i = 0; i < 10; i++ ) STMT } while( 0 )

int main( void )
{
  doTenTimes( { printf( "hello, world\n" ); } );
  return 0;
}

After preprocessing we get this:

int main( void )
{
  do { for (size_t i = 0; i < 10; i++ ) {printf( "hello, world\n" ); } } while (0);
  return 0;
}

It "works", but it's super ugly and made me itch as I wrote it. Don't ever do anything like this.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 1
    Umm so why post such an answer :) The only people who can be trusted with it are those who are already familiar with various bad practices when using function-like macros. The other bunch of the "if something is possible it must be used in my C program" variety really didn't need to know this :) – Lundin Jan 21 '22 at 14:15
  • @Lundin: Pathological need for completeness. It's one of many annoying character flaws of mine. Also hopefully will serve as a warning in case the OP sees code like that in the wild. – John Bode Jan 21 '22 at 14:49
  • For completeness... we could also do this with `setjmp/longjmp` by passing the counter along in the jmp_buf. Doesn't mean that we should :) – Lundin Jan 21 '22 at 14:55
0
#include <stdio.h>

void hello(void) {
    puts("Hello, World!");
}

void byebye(void) {
    puts("Good bye, World!");
}

int main(void) {
    void (*work)(void) = hello;
    for (int i = 0; i < 10; i++) work();
    work = byebye;
    for (int i = 0; i < 10; i++) work();
    return 0;
}

See code running at https://ideone.com/ivsxxR

pmg
  • 106,608
  • 13
  • 126
  • 198
  • It doesn't make much sense to use a function pointer like this though, it would be better to call each function directly. Because all this achieves is to block function inlining. – Lundin Jan 21 '22 at 14:10