最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - How to use global functions inside a module without using a header file - Stack Overflow

programmeradmin1浏览0评论

update: the fix is shown in the code.

I have a function defined in main.cpp. I want to call it inside module Hello. The file Hello.cppm exports module Hello with the implementation in hello.cpp. The files are cut and pasted from larger files so compilation errors may occur. They should be close. (Compiler Explorer IDE wouldn't do modules for me.)

The question is, where can I put the extern declaration in hello.cpp or maybe (it doesn't seem likely) Hello.cppm? I've tried positions before and after the various module statements. Most generate compiler errors. Where it is now, it compiles but won't link. I suspect it is considered a non-exported module Hello function.

It should work in a header file, but can it work without a header file? This a learning experiment. In a header, everything works, but it shouldn't be necessary for a single function.

Using GCC 14.2 and CMake 2.38.2 on Ubuntu 24.04

The linker error.

function `main':
main.cpp:(.text.startup+0x1c): undefined reference to `mod::HelloAgain@Hello::operator()() const'
/usr/bin/ld: libHello.a(hello.cpp.o): in function `mod::Hello@Hello::operator()() const':
hello.cpp:(.text+0x1d): undefined reference to `hello_func_global@Hello[abi:cxx11]()'

main.cpp

#include <iostream>
#include <string>
using namespace std::literals;

auto hello_func_global() -> std::string {
   return "Hello from a global  function."s;
}
import Hello;

auto main() -> int {
   mod::Hello();
   constexpr mod::Hello hello;

   constexpr mod::HelloAgain hello_again;
   hello_again();

   std::cout << hello_func() << '\n';
   return 0;
}

Hello.cppm

module ;

#include <string>

export module Hello;

export namespace mod {
   struct Hello {
      auto operator()() const -> void;
   };
}

hell0.cpp

module Hello;
extern auto hello_func_global() -> std::string; // <=== the fix

using namespace std::literals;

namespace mod {
   auto Hello::operator()() const -> void {
      hello_func_global();
      std::cout << "Hello modules" << '\n';
   }
}

The CMake file that builds the module.

cmake_minimum_required(VERSION 3.28.3)
project(Hello)

add_library(Hello)

target_sources(Hello
               PUBLIC
               FILE_SET CXX_MODULES
               FILES Hello.cppm
               PRIVATE
               hello.cpp
               hello_again.cpp
)

set_target_properties(Hello PROPERTIES CXX_MODULE_TYPE GLOBAL)

update: the fix is shown in the code.

I have a function defined in main.cpp. I want to call it inside module Hello. The file Hello.cppm exports module Hello with the implementation in hello.cpp. The files are cut and pasted from larger files so compilation errors may occur. They should be close. (Compiler Explorer IDE wouldn't do modules for me.)

The question is, where can I put the extern declaration in hello.cpp or maybe (it doesn't seem likely) Hello.cppm? I've tried positions before and after the various module statements. Most generate compiler errors. Where it is now, it compiles but won't link. I suspect it is considered a non-exported module Hello function.

It should work in a header file, but can it work without a header file? This a learning experiment. In a header, everything works, but it shouldn't be necessary for a single function.

Using GCC 14.2 and CMake 2.38.2 on Ubuntu 24.04

The linker error.

function `main':
main.cpp:(.text.startup+0x1c): undefined reference to `mod::HelloAgain@Hello::operator()() const'
/usr/bin/ld: libHello.a(hello.cpp.o): in function `mod::Hello@Hello::operator()() const':
hello.cpp:(.text+0x1d): undefined reference to `hello_func_global@Hello[abi:cxx11]()'

main.cpp

#include <iostream>
#include <string>
using namespace std::literals;

auto hello_func_global() -> std::string {
   return "Hello from a global  function."s;
}
import Hello;

auto main() -> int {
   mod::Hello();
   constexpr mod::Hello hello;

   constexpr mod::HelloAgain hello_again;
   hello_again();

   std::cout << hello_func() << '\n';
   return 0;
}

Hello.cppm

module ;

#include <string>

export module Hello;

export namespace mod {
   struct Hello {
      auto operator()() const -> void;
   };
}

hell0.cpp

module Hello;
extern auto hello_func_global() -> std::string; // <=== the fix

using namespace std::literals;

namespace mod {
   auto Hello::operator()() const -> void {
      hello_func_global();
      std::cout << "Hello modules" << '\n';
   }
}

The CMake file that builds the module.

cmake_minimum_required(VERSION 3.28.3)
project(Hello)

add_library(Hello)

target_sources(Hello
               PUBLIC
               FILE_SET CXX_MODULES
               FILES Hello.cppm
               PRIVATE
               hello.cpp
               hello_again.cpp
)

set_target_properties(Hello PROPERTIES CXX_MODULE_TYPE GLOBAL)
Share Improve this question edited Feb 7 at 18:47 Rud48 asked Feb 6 at 22:33 Rud48Rud48 9234 silver badges16 bronze badges 6
  • Please add the invocation of the compiler. Your example boils down to how wrapping a "h/cpp" pair in a module would kinda look. But one would still need to build/pull those original artefacts. In your case, how is hell0.cpp added to the build? – StoryTeller - Unslander Monica Commented Feb 6 at 23:10
  • @StoryTeller-UnslanderMonica No, it doesn't wrap as you suggest. There are no header files, only modules. I added the CMake file that builds the modules. Everything compiles, but the link fails. If I remove the global function, the project runs. The underlying question is, can you put a global function declaration in a module without including it in a header? If so, how? – Rud48 Commented Feb 7 at 2:30
  • I didn't say you were wrapping, I said that wrapping boils down to something similar, where declarations are exported and the implementation is elsewhere. And since wrapping is fully intended to be possible by the module spec, this example dorsn't appear broken or illegal, and the issue will be with tooling. – StoryTeller - Unslander Monica Commented Feb 7 at 7:02
  • Really? Four downvotes on the question without explanation? – Rud48 Commented Feb 7 at 18:44
  • @StoryTeller-UnslanderMonica As you can see from the accepted answer, it was a coding problem. – Rud48 Commented Feb 7 at 18:45
 |  Show 1 more comment

1 Answer 1

Reset to default 6

I suspect it is considered a non-exported module Hello function.

Exactly.

The question is, where can I put the extern declaration in hello.cpp or maybe (it doesn't seem likely) Hello.cppm?

You don't have any choice but to put it after module Hello;.

To tell the compiler that it is not attached to the module, use a linkage-specification extern "C++".

extern "C++" auto hello_func_global() -> std::string;
发布评论

评论列表(0)

  1. 暂无评论