Submitter:Fred J. Tydeman
Submission Date:2015-06-23
Document: WG14 N1942

Summary

Based upon my reading of the standard, it appears that the following is strictly conforming code. However, many compilers refuse to translate it (which I think is good).

main.c:


#include <string.h>  /* strcpy(), strcmp() */
#undef NDEBUG
#include <assert.h>  /* assert() */

int main(void) {
  int line1;
  int line2;
  char file1[1023];
  char file2[1023];

  #include "file1.h"    /* start of call of assert() split over many files */
  );                    /* end of assert() */

  assert( 2 == line1 );
  assert( 3 == line2 );
  assert( 0 != strcmp( file1, file2 ) );

  return 0;
} /* end main() */


file2.h:


assert(
       ( (void)strcpy(file1,__FILE__), line1 = __LINE__ )

file1.h:


#include "file2.h"
!=
  ( (void)strcpy(file2,__FILE__), line2 = __LINE__ )

There already are some ways to have a macro invocation be split over two files that result in undefined behaviour.

5.1.1.2 Translation phases, paragraph 1, bullet 2 has:

A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character before any such splicing takes place.

which makes using line splicing (as a way to split a macro invocation over many files) undefined.

6.10.3 Macro replacement, paragraph 11 has:

If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives,172) the behavior is undefined.

which makes using #include of arguments (as a way to split a macro invocation over many files) between the outside-most matching parentheses undefined.

Suggested Technical Corrigendum

Add to 5.1.1.2, paragraph 1, bullet 3, words along the lines of:

A macro invocation shall be contained within one source file.