Search code examples
vscode-extensionsclangd

Config default C/C++ standard in VSCode with clangd and FQ bugs


Since I have struggled these warnings/errors for so long. I decided to ask this question and answer myself for late comers.

Extension: vscode-clangd

  1. 'auto' type specifier is a C++11 extensionclang(-Wc++11-extensions) or any "grammar belong to C++11 or later" error. How to set default C/C++ standard in vscode-clangd?

  2. Invalid argument '-std=c99' not allowed with 'Objective-C++' or any header extension .h interpreted as C/C++ conflicting with your standard. How to deal with this annoying bugs?


Solution

  • Solutions

    1. Three ways

      • For small projects: write a compile_flags.txt:
      -std=c++11 
      
      • For big projects: generate complie_commands.json by a build system like CMake, which can be enabled by adding this to your CMakeLists.txt file:
      set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
      
      • If no compilation database(compile_flags.txt/complie_commands.json) is found, you can do this in your vscode:

        • cmd/ctrl + shift + p: Preferences: Open User Settings (JSON)
        • Add these into your settings.json file:
        "clangd.fallbackFlags": [
            "-std=c++11",
            // do not add line below or it will cause conflict
            // "-std=c99",
          ],
        
        
        • cmd/ctrl + shift + p: clangd: Restart language server
    2. You just can't set C & C++ standard into your clangd.fallbackFlags at the same time or it will conflict with each other. Two way to fix this:

      • But you can make your compiler treat your .h as C/C++ by -x
      > man clang
      
      -x <language>
               Treat subsequent input files as having type language.
      

      see: https://stackoverflow.com/a/19413311/17001641

      • or add a .clangd into your project root with these lines:
      If:
        PathMatch: .*\.cpp
      
      CompileFlags:
        Add: [-std=c++20]
      
      ---
      
      If:
        PathMatch: .*\.c
      
      CompileFlags:
        Add: [-std=c99]
      

      see: https://stackoverflow.com/a/76286667/17001641

    Explaination

    clangd first check for a compilation database in the directory containing the source file, and then walk up into parent directories until we find one. The compilation database can be:

    1. a file named compile_commands.json listing commands for each file. Usually generated by a build system like CMake.

    2. a file named compile_flags.txt listing flags to be used for all files. Typically hand-authored for simple projects.

      • easy to use in small projects
    3. If no compilation database is found, use clangd.fallbackFlags.