Search code examples
ccompiler-errorsclangcompiler-warningsclangd

Spurrious clang empty-translation-unit warning


This question has been asked before, but it seems none of the answers apply to my files. I'm using clangd 15.0.7 in VSCode on Windows 11 and macOS 13.2. Please note that gcc 11.3.0, the actual compiler for this project, doesn't emit any warnings. Here's the code :

minmax.h

#ifndef _KPPV_MATH_H_
#define _KPPV_MATH_H_

unsigned int min( unsigned int left, unsigned int right ); /* ISO C requires a translation unit to contain at least one declarationclang(-Wempty-translation-unit) */

unsigned int max( unsigned int left, unsigned int right );

#endif

minmax.c

#include "minmax.h"

unsigned int min( unsigned int left, unsigned int right ) {
    return left < right ? left : right;
}

unsigned int max( unsigned int left, unsigned int right ) {
    return left > right ? left : right;
}

.clangd

CompileFlags:
    Add: [-W, -Wall, -pedantic, -xc, -std=c89, ]
    Remove: [-Wempty-translation-unit]

( The Remove thing obviously doesn't work because of -pedantic -Wall but I don't want people to suggest that, so I included it to show it doesn't work )


Solution

  • The issue stems from the -xc flag in your compile flags. This flags means not only "C language", but more specifically, "a C language source file" as opposed to "a C language header file". Trying to apply this flag to header files will cause some misbehaviour.

    There is instead an -xc-header flag that you can apply to header files.

    Example .clangd file that implements this adjustment:

    # Flags for all files
    CompileFlags:
        Add: [-W, -Wall, -pedantic, -std=c89]
        Remove: [-Wempty-translation-unit]
    
    ---
    
    # Flags for .h files
    If:
      PathMatch: .*\.h
    
    CompileFlags:
      Add: [-xc-header]
    
    ---
    
    # Flags for .c files
    If:
      PathMatch: .*\.c
    
    CompileFlags:
      Add: [-xc]
    

    UPDATE Wanted to mention one other thing: the Add: and Remove: sections under CompileFlags: specify edits to make to the compile command.

    So, Remove: [-Wempty-translation-unit] will only have an effect if the incoming command (from compile_commands.json for example) already contains -Wempty-translation-unit.

    Disabling a warning can be accomplished by adding a flag to disable it, e.g.:

    CompileFlags:
      Add: [-Wno-empty-translation-unit]
    

    That would also work (but I recommend the -xc-header approach for better overall results).