-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[C++20][Modules] '#pragma once' is not well supported #58532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@llvm/issue-subscribers-clang-frontend |
@llvm/issue-subscribers-clang-modules |
@CCCptH Could you post the command lines used to compile these files? There are a few cases around lambdas and template resolution that don't yet fully work with modules. If I am not mistaken, your example uses the Microsoft C++ standard library. You would probably have to apply a workaround in the headers for that library. |
My env is :
I use xmake to build the program. The command line that is used is : clang -c -Qunused-arguments -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -std=c++20 -fmodules -fbuiltin-module-map -fimplicit-modules -fno-implicit-module-maps -fno-ms-compatibility -fmodule-map-file=./module.modulemap -DNDEBUG -fmodule-file=build\.gens\md\windows\x64\release\rules\modules\cache\md.pcm -o build\.objs\md\windows\x64\release\main.cpp.obj main.cpp Thanks a lot. |
@CCCptH Hmm something looks wrong with these commands. C++20 modules should not be confused with the very similar, but compiler-specific Clang modules. Standard C++ modules do not rely on a I think I vaguely remember similar errors to the one you describe being caused by incorrect mixture of the two module variants. |
It is still not working. Env is windows11 and clang15.0.2. The code is : // main.cpp
import md;
#include <iostream>
using namespace std;
int main() {
auto val = func();
cout<<val<<endl;
return 0;
} // md.cppm
module;
#include <iostream>
export module md;
export int func() {
return 0;
} The command line I used is: clang++ -std=c++20 ./md.cppm --precompile -o ./md.pcm
clang++ -std=c++20 main.cpp -fprebuilt-module-path=. md.pcm -o main.exe The compile error is: main.cpp:4:17: warning: using directive refers to implicitly-defined namespace 'std'
using namespace std;
^
main.cpp:8:5: error: missing '#include <iostream>'; 'cout' must be declared before it is used
cout<<val<<endl;
^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\iostream:40:57: note: declaration here is not visible
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT ostream cout;
^
main.cpp:8:16: error: missing '#include <ostream>'; 'endl' must be declared before it is used
cout<<val<<endl;
^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\ostream:1000:51: note: declaration here is not visible
basic_ostream<_Elem, _Traits>& __CLRCALL_OR_CDECL endl(
^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\ostream:273:39: error: no member named 'std' in the global namespace
const _Nput& _Nput_fac = _STD use_facet<_Nput>(this->getloc());
^~~~
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\yvals_core.h:1443:22: note: expanded from macro '_STD'
#define _STD ::std::
~~^
In module 'md' imported from main.cpp:2:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\ostream:273:54: error: unexpected type name '_Nput': expected expression
const _Nput& _Nput_fac = _STD use_facet<_Nput>(this->getloc());
^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\ostream:269:9: error: use of undeclared identifier 'ios_base'
ios_base::iostate _State = ios_base::goodbit;
^
main.cpp:8:9: note: in instantiation of member function 'std::basic_ostream<char>::operator<<' requested here
cout<<val<<endl;
^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\ostream:1003:11: note: in instantiation of member function 'std::basic_ostream<char>::flush' requested here
_Ostr.flush();
^
main.cpp:8:16: note: in instantiation of function template specialization 'std::endl<char, std::char_traits<char>>' requested here
cout<<val<<endl;
^
In module 'md' imported from main.cpp:2:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\ostream:184:16: error: use of undeclared identifier '_Pfn'
return _Pfn(*this);
^
main.cpp:8:14: note: in instantiation of member function 'std::basic_ostream<char>::operator<<' requested here
cout<<val<<endl;
^
1 warning and 15 errors generated. It seems that I can not |
Ok it seems like this is indeed an incompatibility with the Microsoft C++ library. It works with |
This appears to not be Windows related. I'm now hitting similar issues (regarding visibility) when I'm speculating that this has something to do with nested namespaces and/or using directives, but I couldn't pinpoint it yet. |
This seems to be caused by a bug that occurs when using If there is an error like |
It looks like the problem exists after #58716, doesn't it? I think a minimal reproducer in linux would be pretty helpful. (It would be much better if the minimal reproducer doesn't contain |
@ChuanqiXu9 Yes the issue still persists after #58716. However, this seems to be the last remaining issue I could find when trying to build libraries like |
@ChuanqiXu9 I think I could pin it down. It seems like every // invisible.h
#pragma once // This breaks things.
const int kInvisibleSymbol = 0;
struct invisible_struct
{};
#define INVISIBLE_DEFINE // visible.h
#include "invisible.h"
const int kSadlyUndeclaredSymbol = kInvisibleSymbol;
using unfortunately_still_invisible_struct = invisible_struct;
#ifndef INVISIBLE_DEFINE
# error "Still not defined."
#endif // implementation.cpp
module;
#include "visible.h"
module mymodule; // interface.cppm
module;
#include "visible.h"
export module mymodule; The step that fails is the compilation of visible.h:3:41: error: missing '#include "invisible.h"'; 'kInvisibleSymbol' must be declared before it is used
const int kSadlyUndeclaredSymbol = kInvisibleSymbol;
^
invisible.h:3:11: note: declaration here is not visible
const int kInvisibleSymbol = 0;
^
In file included from implementation.cpp:3:
visible.h:5:46: error: missing '#include "invisible.h"'; 'invisible_struct' must be declared before it is used
using unfortunately_still_invisible_struct = invisible_struct;
^
invisible.h:5:8: note: declaration here is not visible
struct invisible_struct
^
In file included from implementation.cpp:3:
visible.h:8:6: error: "Still not defined."
# error "Still not defined."
^
3 errors generated. |
It seems undesirable to implement another system for tracking which included headers are transitively visible through inclusions in order to support |
Oh, it makes sense if you refer
Cool, it looks like a possible solution. And I am wondering if we can solve the problem by treating every included header in a named module as invisible. I feel like this is workable since named modules have different semantics than header modules. |
Copying my minimal reproducer from #59708 // a.hpp
#pragma once
using a = int; // b.hpp
#pragma once
#include "a.hpp"
a b; // c.cpp
module;
#include "b.hpp"
export module c; Causes Clang to error with In file included from c.cpp:3:
b.hpp:4:1: error: unknown type name 'a'
a b;
^ |
I think this is in fact a duplicate of #38554. |
Uh oh!
There was an error while loading. Please reload this page.
I am trying to write some codes in C++20 standard. I write some simple code in C++ module way. And I write
#include <iostream>
becauseimport <iostream>
can not be compiled in clang-15.0.2 compiler. Then I meet compile error.The code is:
Compile error is:
And If I delete
#include<iostream>
in filemd.ixx
. It can be successfully compiled.So is there any solution to using
<iostream>
in bothmain.cpp
andmd.ixx
?The text was updated successfully, but these errors were encountered: