Skip to content
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

Error when importing <string> and <iostream> in same file with c++-20 standard modules #58540

Open
mls-m5 opened this issue Oct 22, 2022 · 7 comments
Assignees
Labels
clang:modules C++20 modules and Clang Header Modules

Comments

@mls-m5
Copy link

mls-m5 commented Oct 22, 2022

I get a compilation error when trying to import <string> and <iostream> in the same file. Something seems to be off.

This is what I have tried this far. (based on instructions from clang)

clang++-16 -std=c++20 -stdlib=libc++ -xc++-system-header --precompile "/usr/lib/llvm-16/include/c++/v1/iostream"  -o  "iostream.pcm" -Wno-pragma-system-header-outside-header -Wno-user-defined-literals 
clang++-16 -std=c++20 -stdlib=libc++ -xc++-system-header --precompile "/usr/lib/llvm-16/include/c++/v1/string"  -o  "string.pcm" -Wno-pragma-system-header-outside-header -Wno-user-defined-literals 
clang++-16 -std=c++20 -stdlib=libc++ "apa.cpp"  -fmodule-file="iostream.pcm" -fmodule-file="string.pcm"  -c -o  "apa.o" 
// apa.cpp
import <iostream>;
import <string>;

int print() {
    std::cout << "hello" << std::endl;
    return 10;
}

Note that it compiles when I remove the line

    std::cout << "hello" << std::endl;

Also: When just importing <iostream> it seems to work, so that might be a possible temporary workaround, and iostream seems to define std::string. I don't think it's standard but it kind of works until the bug is fixed. Like this:

import <iostream>;
// import <string>;

int print() {
    std::cout << "hello" << std::endl;
    std::string str = "satnhoeu";
    return 10;
}

The error message I get is

In module '/usr/lib/llvm-16/include/c++/v1/iostream':
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:301:5: error: 'std::basic_string_view<char>::basic_string_view' from module '/usr/lib/llvm-16/include/c++/v1/iostream' is not present in definition of 'std::string_view' in module '/usr/lib/llvm-16/include/c++/v1/string'
    basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
    ^
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:267:5
: note: definition has no member 'basic_string_view'
    basic_string_view {
    ^
In module '/usr/lib/llvm-16/include/c++/v1/iostream':
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:295:5: error: 'std::basic_string_view<char>::basic_string_view' from module '/usr/lib/llvm-16/include/c++/v1/iostream' is not present in definition of 'std::string_view' in module '/usr/lib/llvm-16/include/c++/v1/string'
    basic_string_view(const basic_string_view&) _NOEXCEPT = default;
    ^
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:267:5: note: definition has no member 'basic_string_view'
    basic_string_view {
    ^
In module '/usr/lib/llvm-16/include/c++/v1/iostream':
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:292:5: error: 'std::basic_string_view<char>::basic_string_view' from module '/usr/lib/llvm-16/include/c++/v1/iostream' is not present in definition of 'std::string_view' in module '/usr/lib/llvm-16/include/c++/v1/string'
    basic_string_view() _NOEXCEPT : __data_ (nullptr), __size_(0) {}
    ^
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:267:5: note: definition has no member 'basic_string_view'
    basic_string_view {
    ^
In module '/usr/lib/llvm-16/include/c++/v1/iostream':
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:312:37: error: 'std::basic_string_view<char>::basic_string_view' from module '/usr/lib/llvm-16/include/c++/v1/iostream' is not present in definition of 'std::string_view' in module '/usr/lib/llvm-16/include/c++/v1/string'
    constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)
                                    ^
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:267:5: note: definition has no member 'basic_string_view'
    basic_string_view {
    ^
In module '/usr/lib/llvm-16/include/c++/v1/iostream':
/usr/lib/llvm-16/bin/../include/c++/v1/string_view:339:5: 
error: 'std::basic_string_view<char>::basic_string_view' from module '/usr/lib/llvm-16/include/c++/v1/iostream' is not present in definition of 'std::string_view' in module '/usr/lib/llvm-16/include/c++/v1/string'
    basic_string_view(const _CharT* __s)
    ^
...

I have also tried to compile the header units with

clang++-16 -std=c++20 -stdlib=libc++ -fmodule-header=system -xc++-header "iostream"  -o  "iostream.pcm" -Wno-pragma-system-header-outside-header -Wno-user-defined-literals 
build "string.pcm"
clang++-16 -std=c++20 -stdlib=libc++ -fmodule-header=system -xc++-header "string"  -o  "string.pcm" -Wno-pragma-system-header-outside-header -Wno-user-defined-literals 

But get the same result

@llvmbot
Copy link
Collaborator

llvmbot commented Oct 22, 2022

@llvm/issue-subscribers-clang-modules

@tbaederr tbaederr added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 22, 2022
@aaronmondal
Copy link
Member

aaronmondal commented Oct 23, 2022

@mls-m5 While it is not a proper solution, a workaround is changing -fmodule-file=iostream.pcm to -fmodule-file=iostream=iostream.pcm, (and doing the same for string) and using #includes in the global module fragment. This way we still use the precompiled header units. This is of course not ideal. The code you posted should work without errors.

The workaround works because without naming the modules the headers files will essentially be loaded twice, (i think the module resolution does not respect the include guards or something, so we need to rely on overload resolution which fails here) - once for the regular clang import and once for the manually loaded .pcm. When naming the modules, clang seems to be able to correctly resolve the duplicates.

This seems to be another example of an known issue where we need explicit template deduction guides in libcxx. Running the final command with -ferror-limit=100 gives me this buggy error:

In module '/usr/include/c++/v1/iostream':
/usr/include/c++/v1/locale:1442:37: error: no matching member function for call to 'data'
        if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
                               ~~~~~^~~~
/usr/include/c++/v1/ostream:763:17: note: in instantiation of function template specialization 'std::__pad_and_output<char, std::char_traits<char>>'
      requested here
            if (__pad_and_output(_Ip(__os),
                ^
/usr/include/c++/v1/ostream:902:19: note: in instantiation of function template specialization 'std::__put_character_sequence<char,
      std::char_traits<char>>' requested here
    return _VSTD::__put_character_sequence(__os, __str, _Traits::length(__str));
                  ^
apa.cpp:5:15: note: in instantiation of function template specialization 'std::__1::operator<<<std::char_traits<char>>' requested here
    std::cout << "hello" << std::endl;
              ^
/usr/include/c++/v1/string:1279:23: note: candidate function not viable: no known conversion from 'basic_string<...>' to 'const basic_string<...>' for
      object argument
    const value_type* data() const _NOEXCEPT  {return std::__to_address(__get_pointer());}
                      ^
/usr/include/c++/v1/string:1282:17: note: candidate function not viable: no known conversion from 'basic_string<...>' to 'basic_string<...>' for object
      argument
    value_type* data()             _NOEXCEPT  {return std::__to_address(__get_pointer());}
                ^

I'll try to come up with a fix.

@mls-m5
Copy link
Author

mls-m5 commented Oct 23, 2022

Ok thanks for the response, and thanks for the workaround. One wierd problem I noticed with using the syntax file=iostream=iostream.pcm is that when using that if I try that with a import <...>-statement i get errors like.

# Paths are a litle bit different when i run, I leave them in if they are the problem.
clang++-16 -std=c++20 -stdlib=libc++ -xc++-system-header --precompile iostream  -o  "build/.mm3/default/iostream.pcm" -Wno-pragma-system-header-outside-header -Wno-user-defined-literals 
clang++-16 -std=c++20 -stdlib=libc++ "apa.cpp"  -fmodule-file="<iostream>=build/.mm3/default/iostream.pcm"  -c -o  "build/.mm3/default/apa.o"
apa.cpp:6:8: error: header file <iostream> (aka '/usr/lib/llvm-16/bin/../include/c++/v1/iostream') cannot be imported because it is not known to be a header unit
import <iostream>;
       ^
apa.cpp:10:5: error: use of undeclared identifier 'std'
    std::cout << "hello" << std::endl;
    ^
apa.cpp:10:29: error: use of undeclared identifier 'std'
    std::cout << "hello" << std::endl;
                            ^
apa.cpp:11:5: error: use of undeclared identifier 'std'
    std::string str = "satnhoeu";
    ^
4 errors generated.

It seems likei will have to handle dependencies differently if I include or when i import. (Maybe a separate issue, but I thought it should work.)

Code used in that experiment

import <iostream>;

int print() {
    std::cout << "hello" << std::endl;
    std::string str = "satnhoeu";
    return 10;
}

mls-m5 added a commit to mls-m5/matmake3 that referenced this issue Oct 23, 2022
@ChuanqiXu9 ChuanqiXu9 self-assigned this Oct 27, 2022
@ChuanqiXu9
Copy link
Member

I assigned myself to add this one to my TODO list. But to be honest, I prefer named modules than header units so the priority of this task is relatively low to me. (I have many TODOs...) So if any one want to look at this, feel free to take it.

@mls-m5
Copy link
Author

mls-m5 commented Oct 27, 2022

I did not realize before now that import std was going to be standard. I would also prefer that solution when will work in c++23.

mls-m5 added a commit to mls-m5/rym that referenced this issue Nov 14, 2022
Started using clang++16 and update my module knowledge and compile with matmake3

* Started using clang++-16 not finished yet

* Experiments to solve problems with gl functions

* It compiles

* Workaround for clang bug that prevents importing string and iostream

Described here
llvm/llvm-project#58540
https://stackoverflow.com/questions/74149849/error-when-importing-string-and-iostream-in-same-file?noredirect=1#comment130924685_74149849

* Restructure draw shaderprogram and remove namespace obj

* Fix to clang-related issue

* First actual working build with matmake3 and real modules with
clang

* Replace include statements with import statements

* Remove old broken code

* Update CI workflow
@philnik777
Copy link
Contributor

Does this have anything to do with libc++? If not, I think we should remove the tag.

@ChuanqiXu9 ChuanqiXu9 removed the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jan 16, 2023
@ChuanqiXu9
Copy link
Member

Does this have anything to do with libc++? If not, I think we should remove the tag.

No, almost of the header units issues should be unrelated to the standard libraries. Since the intention of header units is to import existing and old libraries. So it is meaningless to me that we need to refactor the current header to make it importable for header units.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:modules C++20 modules and Clang Header Modules
Projects
None yet
Development

No branches or pull requests

6 participants