A smart way to prototype functions

I am looking for a (clean) way of writing a function definition and a function prototype without duplicating code. Since DRY has established itself as a good idea and manual prototyping in header files is a clear violation, this seems like a reasonable requirement.

The sample code below shows a (rough) way to solve a preprocessor problem. It seems unlikely to be optimal, but it seems to work correctly.

Using separate files and duplication:

foo.h:
#ifndef FOO_H
  #define FOO_H
  // Normal header file stuff
  int dofoo(int a);
#endif /* FOO_H */

foo.c:
#include "foo.h"
int dofoo(int a) {
  return a * 2;
}

Using C preprocessor:

foo.h:
#ifndef FOO_H
  #define FOO_H

  // Normal header file stuff

  #ifdef PROTOTYPE // if incorrect:
  // No consequences for this test case, but we lose a sanity check
    #error "PROTOTYPE set elsewhere, include mechanism will fall over"
  #endif

  #define PROTOTYPE // if incorrect:
  // "error: redefinition of 'dofoo'" in clang & gcc, 
  // referring to int dofoo() line in foo.c
    #include "foo.c"
  #undef PROTOTYPE //if incorrect:
  // No warnings, but should trigger the earlier #error statement if
  // this method is used in more than one file

#endif /* FOO_H */

foo.c:
#include "foo.h"

int dofoo (int a)
#ifdef PROTOTYPE // if incorrect:
// "error: redefinition of 'dofoo'" in clang & gcc, 
// referring to int dofoo() line in foo.c
  ;
#else
  {
    return a * 2;
  }
#endif

- .h .c! . , . , .

, .

  • , .
  • (, sqlite makeheaders)

, . C - 25 , , , .

, .

edit: gcc 4.8.2 clang 5.1 . #endif ( , ) "error: unterminated #else" "error: unterminated ", #ifdef.

#else , C. gcc "error: '(' before '{' " clang " ". , , #else .

PROTOTYPE wrong , , . , , , , , .

+4
2

1), .

, , . -, , . , , , , . , .

, - , , #endif - . , foo.c PROTOTYPE.

+5

. DRY, , , .

, , . , ( ) , , /.

, . , .. #ifdef PROTOTYPE... #else ... #endif, , . -, , , .

, , , . -, , - . c.

, , .

+1

Source: https://habr.com/ru/post/1543997/


All Articles