Multiple definition error when importing c++23 standard library module in multiple files.

huangapple go评论141阅读模式
英文:

Multiple definition error when importing c++23 standard library module in multiple files

问题

以下是要翻译的内容:

I was trying out the c++23 Standard Library Modules (P2465R3) with Visual Studio 17.8.0 Preview 1.0.

When using just the one file everything works as expected and the following compiles and runs:

  1. // main.cpp
  2. import std;
  3. int main() {
  4. std::print("Hello Modules\n");
  5. }

But once I try to use multiple files I get a linker error:

  1. // test.ixx
  2. export module test;
  3. import std;
  4. export void do_test() {
  5. std::print("test\n");
  6. }
  7. // main.cpp
  8. import std;
  9. import test;
  10. int main() {
  11. std::print("Hello Modules\n");
  12. do_test();
  13. }

LNK2005 "class std::basic_string_view<char,struct std::char_traits<char> > $S3" ?$S3@@3V?$basic_string_view@DU?$char_traits@D@std@@@std@@A) already defined in main.obj

Is this the expected behavior? And if so, how would I go about importing the standard library modules in multiple files?

EDIT:
I noticed that I still get the link error even if I replace import std; with import <print>; in both main.cpp and test.ixx, so this is probably an issue with modules as a whole and not just the Standard Library Modules.

英文:

I was trying out the c++23 Standard Library Modules (P2465R3) with Visual Studio 17.8.0 Preview 1.0.

When using just the one file everything works as expected and the following compiles and runs:

  1. // main.cpp
  2. import std;
  3. int main() {
  4. std::print(&quot;Hello Modules\n&quot;);
  5. }

But once I try to use multiple files I get a linker error:

  1. // test.ixx
  2. export module test;
  3. import std;
  4. export void do_test() {
  5. std::print(&quot;test\n&quot;);
  6. }
  7. // main.cpp
  8. import std;
  9. import test;
  10. int main() {
  11. std::print(&quot;Hello Modules\n&quot;);
  12. do_test();
  13. }

LNK2005 &quot;class std::basic_string_view&lt;char,struct std::char_traits&lt;char&gt; &gt; $S3&quot; ?$S3@@3V?$basic_string_view@DU?$char_traits@D@std@@@std@@A) already defined in main.obj

Is this the expected behavior? And if so, how would I go about importing the standard library modules in multiple files?

EDIT:
I noticed that I still get the link error even if I replace import std; with import &lt;print&gt;; in both main.cpp and test.ixx, so this is probably an issue with modules as a whole and not just the Standard Library Modules.

答案1

得分: 1

我最近才开始使用 import std,所以不能确定,但问题可能出在 std::print 的实现上,而不是一般的模块。

一开始,我按照你的写法运行了测试程序。结果出现了与你遇到的链接错误相同的问题。然而,当我从你的测试程序中删除了 std::print,并用 std::cout << std::format 替代它时,程序运行正常。

这个版本使用了 main.ixx 模块:
  1. // main.ixx
  2. export module main;
  3. import std;
  4. import test;
  5. export int main() {
  6. std::cout << std::format("Hello Modules\n");
  7. //std::print("Hello Modules\n");
  8. do_test();
  9. }
  1. // test.ixx
  2. export module test;
  3. import std;
  4. export void do_test() {
  5. std::cout << std::format("test\n");
  6. //std::print("test\n");
  7. }
我还测试了不为 main 制作模块的版本:
  1. // main.cpp
  2. import std;
  3. import test;
  4. int main() {
  5. std::cout << std::format("Hello Modules\n");
  6. //std::print("Hello Modules\n");
  7. do_test();
  8. }
  1. // test.ixx
  2. export module test;
  3. import std;
  4. export void do_test() {
  5. std::cout << std::format("test\n");
  6. //std::print("test\n");
  7. }

这两个版本都正常运行。

我对 import std 的实验通常都很顺利。它们仍然处于实验阶段,涉及到我编写的大约十几个不同的模块。一开始,一些模块导入了各个标准库头文件,像 import <vector> 这样的语句,等等。这些与使用 import std 的模块不兼容,出现了类似于你遇到的链接错误的奇怪错误。当我将所有东西都切换到 import std 时,这些错误就消失了,从那以后一切都很顺利。

不必一次又一次地弄清楚哪个头文件需要在哪里包含,这是一个真正的优点。这一点使我对模块的进展感到积极。

英文:

I have only begun using import std very recently, so I cannot say for sure, but the problem may be with the implementation of std::print, rather than modules in general.

At first, I ran the test program exactly as you wrote it. That gave me the same link error as you got. When I eliminated std::print from your test program, however, replacing it with std::cout &lt;&lt; std::format, the program ran fine.

This version uses a module for main.ixx:
  1. // main.ixx
  2. export module main;
  3. import std;
  4. import test;
  5. export int main() {
  6. std::cout &lt;&lt; std::format(&quot;Hello Modules\n&quot;);
  7. //std::print(&quot;Hello Modules\n&quot;);
  8. do_test();
  9. }
  1. // test.ixx
  2. export module test;
  3. import std;
  4. export void do_test() {
  5. std::cout &lt;&lt; std::format(&quot;test\n&quot;);
  6. //std::print(&quot;test\n&quot;);
  7. }
I also tested without making a module for main:
  1. // main.cpp
  2. import std;
  3. import test;
  4. int main() {
  5. std::cout &lt;&lt; std::format(&quot;Hello Modules\n&quot;);
  6. //std::print(&quot;Hello Modules\n&quot;);
  7. do_test();
  8. }
  1. // test.ixx
  2. export module test;
  3. import std;
  4. export void do_test() {
  5. std::cout &lt;&lt; std::format(&quot;test\n&quot;);
  6. //std::print(&quot;test\n&quot;);
  7. }

Both versions ran correctly.

My experiments with import std have generally gone well. They are still at the experimental stage, involving roughly a dozen different modules I have coded. At first, a few of the modules imported individual Standard Library headers, with statements such as import &lt;vector&gt;, and so on. Those did not play well with the modules that used import std. There were weird errors akin to the linker error you encountered. When I switched everything to import std, those errors went away, and it has been clear sailing ever since.

It is a real plus not to have to figure out over and over again which header file needs to be included where. That alone has left me with a positive feeling about the progress being made with modules.

huangapple
  • 本文由 发表于 2023年8月10日 21:40:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76876289.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定