Backslash newline at end of file warning

后端 未结 6 1606
猫巷女王i
猫巷女王i 2020-12-20 12:59

With this code:

#include 


int main(int argc, char *argv[])
{

  return 0;
}


/** run2: A macro to call a function. */
#define run2( functi         


        
相关标签:
6条回答
  • 2020-12-20 13:26

    May be the last line in your file doesn't terminate with a newline? The final newline at the end of a file is required but there are editors that just for the fun of being annoying don't write it (IIRC visual studio).

    0 讨论(0)
  • 2020-12-20 13:27

    The problem is that there's no new-line character in the end of your code. C++ Standard §2.1/2 says:

    <...>If a source file that is not empty does not end in a new-line character, or ends in a new-line character immediately preceded by a backslash character, the behavior is undefined.

    0 讨论(0)
  • 2020-12-20 13:30

    At a guess, what you're missing is a new-line following the final closing brace. It's reasonable for the compiler to warn about that (the C and C++ standards say it gives undefined behavior), but the text of the message is misleading about the source of the problem.

    0 讨论(0)
  • 2020-12-20 13:40

    The following code generates the same warning under g++ 4.3.4 and g++ 4.5.1:

    int main() {}
    #define X \
    Y
    

    I must say I don't understand why. But you can get rid of the warning by adding an empty line at the end of the file.

    Incidentally, this compiles without a warning, even without an empty last line:

    int main() {}
    #define X Y
    

    So it looks like a pre-processor bug to me.

    Edited to add: OK, not a bug as such. See my other answer for a more considered view.

    0 讨论(0)
  • 2020-12-20 13:42

    As Kirill V. Lyadvinsky pointed out, the current standard insists on a newline at the end of every source file. Fortunately, the behaviour on non-conforming input is undefined, so compilers are free to ignore this silly rule. Mostly they do. But the standard leaves the pre-processor free to reject such cases, and you seem to have stumbled on such a case. Surely g++ doesn't reject it out of pique? So it must be (not a bug, because the standard allows it, but) unintended behaviour.

    The good news is that C++11 gets it right:

    2.2 Phases of translation
    A source file that is not empty and that does not end in a new-line character, or that ends in a new-line character immediately preceded by a backslash character before any such splicing takes place, shall be processed as if an additional new-line character were appended to the file.

    So your code will compile in the near future.

    0 讨论(0)
  • 2020-12-20 13:52

    Having your file(translation unit) not end in a newline is undefined behavior which means the behavior of your program becomes unpredictable. Although in C++11 this changes and the pre-processor will behave as if a new-line was there.

    It is interesting to note why this is an issue, we can from the draft pre C++11 standard that including a file via include has the following effect from section 16.2 Source file inclusion which says:

    A preprocessing directive of the form

     # include " q-char-sequence" new-line
    

    causes the replacement of that directive by the entire contents of the source file identified by the specifie sequence between the " delimiters.

    so if the included files does not end in a newline how should we deal with the combined last line of the included file and the subsequent line in the source code? There are several obvious issues, for example if the last line in the included file ends:

    • in a comment
    • in a continuation
    • in a macro definition

    it will alter the way the source file using the include will be interpreted which is not a desirable feature. This is also covered in the The New C Standard(C also has the same rule) and it says:

    What should the behavior be if the last line of an included file did not end in a new-line? Should the characters at the start of the line following the #include directive be considered to be part of any preceding preprocessing token (from the last line of the included file)? Or perhaps source files should be treated as containing an implicit new-line at their end. This requirement simplifies the situation by rendering the behavior undefined

    For completeness sake, pre C++11 the draft standard section 2.1 Phases of translation says (emphasis mine going forward):

    [...]If a source file that is not empty does not end in a new-line character, or ends in a new-line character immediately preceded by a backslash character, the behavior is undefined.

    and the C++11 draft standard says:

    [...]A source file that is not empty and that does not end in a new-line character, or that ends in a new-line character immediately preceded by a backslash character before any such splicing takes place, shall be processed as if an additional new-line character were appended to the file.

    0 讨论(0)
提交回复
热议问题