问题:clangd在处理同时包含include和import声明的源文件时似乎无法正确反序列化,因此它认为代码存在ODR(One Definition Rule,单一定义规则)违规。然而,代码实际编译和运行完全正常且无警告。我该如何解决clangd的错误提示?
提供的示例中,有一个简单的模块:
// some_module.cpp
module;
#include <string>
export module SomeModule;
export std::string HelloWorld() {
return "Hello, World!";
}
在使用此模块时,clangd会报告ODR违规:
// main.cpp
#include <iostream>
import SomeModule; // clangd 报告:
// 在包含文件中:'std::basic_string' 在不同模块中有不同的定义;
// 第一个差异是在模块 'SomeModule.<global>' 中找到没有默认参数的模板参数
// (module_odr_violation_template_parameter)
int main() {
std::cout << HelloWorld() << std::endl;
return 0;
}
如何解决这个问题?应从何处着手?
[编辑]
主模块接口以及main中的include语句都按照LLVM的推荐方式进行(例如,在全局模块片段中进行include,并在import之前进行include):
https://clang.llvm.org/docs/StandardCPlusPlusModules.html#including-headers-after-import-is-problematic
因此,问题不在于如何正确地将include与import一起使用(clang-17可以完美编译上述提供的代码),而在于如何配置clangd以停止发出ODR错误提示。
附上CMakeLists.txt文件(完整代码可在<a href="https://github.com/ZhalgasFromMSU/clangd">GitHub</a>上查看):
# CMakeLists.txt
cmake_minimum_required(VERSION 3.28)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(example CXX)
add_executable(main
main.cpp
)
target_sources(main
PUBLIC FILE_SET modules TYPE CXX_MODULES FILES
some_module.cpp
)