I don't understand why
I saw import std.core; here
I can't import std;
I can't import std.iostream;
I can #include <iostream>
Can you explain why above is happening? Maybe i guess std.iostream is not a module. Then why 1. works?
#Someprogrammerdue provided this reference, and its says
import <iostream>; // import declaration
When I run following in my compiler
import <iostream>;
int main()
{
return 0;
}
I get
main.cpp:1:8: error: 'iostream' was not declared in this scope
1 | import<iostream>;
Why is this happening?
I don't understand why
I saw import std.core; here
You saw what you did because you read the page and that's what was written there.
I can't import std;
This is because the C++20 standard library doesn't define modules. And because no other library can (or shouldn't) define module std because that module name is reserved for language implementation / future standardisation.
I can't import std.iostream;
See 2.
I can #include <iostream>
That header is part of the C++20 standard library.
Then why 1. works?
The MSVC documentation explains:
Although not specified by the C++20 standard, Microsoft enables its implementation of the C++ Standard Library to be imported as modules.
P.S. Support for modules is at the moment of writing only partially implemented by all major compilers with the exception of MSVC which appears to have full implementation since 19.28 (the modular standard libary is not a requirement for this).
P.P.S. Modular standard library is planned for C++23.
import std;
Improvement in compilation time.
According to ISO C++23, there is also import std.compat;.
Differences between the two are as follows (extracted from P2465R3):
import std; imports everything in namespace std from C++ headers (e.g. std::sort from <algorithm>) and C wrapper headers (e.g. std::fopen from <cstdio>). It also imports ::operator new etc. from <new>.
import std.compat; imports all of the above, plus the global namespace counterparts for the C wrapper headers (e.g. ::fopen).
import ... is said to be much faster to compile than #include ....
Interview with Bjarne Stroustrup (InfoWorld): C++ 23 to introduce module support.
P.S. Modules are not supported fully by most compilers yet. For MSVC users, please, refer to this link.
(https://learn.microsoft.com/en-us/cpp/cpp/tutorial-import-stl-named-module?view=msvc-170).
Related
I've been trolling through the messages and haven't found an updated answer to Xcode support for C++20 modules. Apologies if I missed it.
Right now, all I'm trying to do is use the import directive to import a C++ Standard Library file.
import <iostream>;
import <string>;
import <memory>;
This produces an error of "Use of undeclared identifier 'iostream'" as well as "Use of undeclared identifier 'string'" (same for memory).
For my Project Build Settings I have:
My C++ Language Dialect: GNU++20 [-std=gnu++20]
Compile for C/C++/Objective-C: Default compiler (Apple Clang)
Would appreciate help with this. Thank you.
Sorry if i ask again about "moudules" in C++.
Im using g++ gcc-c++-12.2.1-4.fc37.x86_64 in fedora 37 linux and vscode.
So i said: i will upgrade my knowladge with the book "A tour of C++ third edition" which its updated to c++20 standard.
The thing that the first program:
import std;
int main()
{
std::cout << "Hello, World!\n";
}
Doesn't compile.
I have enabled "std=c++20" and "-fmodules-ts" and also tried "-std=gnu++20".
The output is this, its like the compiled modules are missing:
std: error: failed to read compiled module: No existe el fichero o el directorio
std: nota: compiled module file is ‘gcm.cache/std.gcm’
std: nota: imports must be built before being imported
std: error fatal: returning to the gate for a mechanical issue
Ok it's in spanish becouse is my native tongue.
Any help?
import std;
This line of code requires not only module support, but also Standard Library Modules (P2465R3 Standard Library Modules std and std.compat) that's part of C++23.
From the Compiler support for C++23 page on cppreference, we can see that it's still not supported by GCC libstdc++.
As OP mentioned that the code snippet is taken from Bjarne's book, I double-checked section 1.2 of it. In the paragraph after the next from the code snippet containing import std;, it's stated that this is not yet standard:
The import directive is new in C++20 and presenting all of the standard library as a module std is not yet standard. [...]
I am experimenting with modules in clang, and would like to include the standard lib as modules instead of as includes.
Currently I do this
#include <iostream>
#include <string>
It seems that you in msvc should be able to import standard libs with for example
import std.core;
When using clang however this does not seem to be implemented, or implemented in another way.
My question is: Is it possible to import stl-includes like microsoft suggest, or is it possible to map standard lib includes to modules somhow.
Note: The reason I cannot use #include <...> or #import <...> is because of other errors that might get its own question. So I think that getting import std.core or similar is the way to go now if it is possible.
ModernesCpp also mentions std.core.
The C++20 standard does not include module definitions for the C++ standard library. Visual Studio does (unfortunately), and a lot of bad sites out there will act like this is standard. But it's not; it's just a Microsoft thing.
If you want to include the C++ standard library through a module across platforms, you will have to either use import <header-name> syntax or write your own standard library modules that import the headers and export specific C++ declarations.
I solved your task. Below are instructions for doing this. I did this on my Win 10 64-bit using CLang from current release of LLVM 12.0 (taken from here), also I have MSVC 2019 v16.9.4 Community installed (taken from here).
Note. This answer is for CLang only, I also wrote similar answer for MSVC.
First create following files:
module.modulemap:
module std_mod {
requires cplusplus17
header "std_mod.hpp"
export *
}
std_mod.hpp:
#include <iostream>
#include <map>
#include <set>
#include <vector>
use.cpp:
import std_mod;
int main() {
std::cout << "Hello, World!" << std::endl;
}
In above file std_mod.hpp you can put any std headers that you need. You should put all possible STD headers that you use in all your projects, to be able to share same precomiled STD module everywhere.
Then execute command:
clang++ -### use.cpp -c -std=c++20 -m64 -g -O3 >use.txt 2>&1
Here instead of -std=c++20 -m64 -g -O3 you may use any options needed for your project. Every precompiled module should have same compilation options as other .cpp files to be able to be linked into final binary.
Command above will produce use.txt with options that you need to copy. In this options you should remove -emit-obj option, -o option (and path after it), also remove use.cpp. Then add to this command options string module.modulemap -o std_mod.pcm -emit-module -fmodules -fmodule-name=std_mod. On my system I got following resulting command:
"D:\\bin\\llvm\\bin\\clang++.exe" "-cc1" module.modulemap -o std_mod.pcm -emit-module -fmodules -fmodule-name=std_mod "-triple" "x86_64-pc-windows-msvc19.28.29914" "-mincremental-linker-compatible" "--mrelax-relocations" "-disable-free" "-disable-llvm-verifier" "-discard-value-names" "-main-file-name" "use.cpp" "-mrelocation-model" "pic" "-pic-level" "2" "-mframe-pointer=none" "-fmath-errno" "-fno-rounding-math" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-gno-column-info" "-gcodeview" "-debug-info-kind=limited" "-resource-dir" "D:\\bin\\llvm\\lib\\clang\\12.0.0" "-internal-isystem" "D:\\bin\\llvm\\lib\\clang\\12.0.0\\include" "-internal-isystem" "d:\\bin2\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29910\\include" "-internal-isystem" "d:\\bin2\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29910\\atlmfc\\include" "-internal-isystem" "D:\\Windows Kits\\10\\Include\\10.0.19041.0\\ucrt" "-internal-isystem" "D:\\Windows Kits\\10\\include\\10.0.19041.0\\shared" "-internal-isystem" "D:\\Windows Kits\\10\\include\\10.0.19041.0\\um" "-internal-isystem" "D:\\Windows Kits\\10\\include\\10.0.19041.0\\winrt" "-O3" "-std=c++20" "-fdeprecated-macro" "-fdebug-compilation-dir" "D:\\t\\t4" "-ferror-limit" "19" "-fno-use-cxa-atexit" "-fms-extensions" "-fms-compatibility" "-fms-compatibility-version=19.28.29914" "-fdelayed-template-parsing" "-fno-implicit-modules" "-fcxx-exceptions" "-fexceptions" "-vectorize-loops" "-vectorize-slp" "-faddrsig" "-x" "c++"
As you can see this command contains full paths to includes, they are necessary. Execute command above, it will produce std_mod.pcm that you can use in your projects everywhere with same compilation options.
Why long command above is needed? Because using .modulemap file is possible only through -cc1 command, which executes low-level CLang front end instead of simplified CLang driver (driver is without -cc1 option). This low level front-end is possible to do many tricks which driver can't do.
Now you can compile your final program use.cpp that does import std_mod; by next command:
clang++ use.cpp -o use.exe -std=c++20 -m64 -g -O3 -fmodule-file=std_mod.pcm
See that I added -fmodule-file=std_mod.pcm - such option is needed for every imported module. As alternative you can use -fprebuilt-module-path=<directory> to specify where to search for all prebuilt modules.
Not long time ago I also created question and answer here regarding how to make modules out of headers in CLang.
For further instructions regarding modules see CLang's Modules Doc and CommandLine Doc.
PS. Why I implemented quite long solution above? Because at least on Windows' CLang next simple program
import <iostream>;
int main() {}
doesn't compile, it says use.cpp:1:8: error: header file <iostream> (aka 'd:\bin2\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\iostream') cannot be imported because it is not known to be a header unit. So at least on Win one needs a special solution, solution with import <header-name>; doesn't work here.
All headers imported through import <header>; or import "header"; syntax should have special compiled header unit modules placed into special folder to be able to use. And on Win STD headers don't have corresponding compiled header unit modules. Also after spending many hours I didn't find a way in CLang how to create these so-called header units on Win. Only solution above solved my task of importing headers as modules.
I found where I got the Idea, llvms documentation. There is a section stating
"As an example, the module map file for the C standard library might look a bit like this:"
module std [system] [extern_c] {
module assert {
textual header "assert.h"
header "bits/assert-decls.h"
export *
}
module complex {
header "complex.h"
export *
}
module ctype {
header "ctype.h"
export *
}
module errno {
header "errno.h"
header "sys/errno.h"
export *
}
module fenv {
header "fenv.h"
export *
}
// ...more headers follow...
}
It seems that you then name this file something.modulemap and send it to the compiler. A quick googling did not find any similar solution for msvc (other than std.io discussed earlier).
I have not tried it out yet, i guess i will accept my own answer when I have, or if somebody else comes up with something better.
I am now trying to build a c++ library in linux with cmake. If I do not enable -std=c++0x option, I always get compilation errors error: 'div_t' was not declared in this scope for the following codes:
int xPos;
div_t divResult;
divResult = div(xPos,8);
Then if I enable -std-c++0x options with cmake: set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x", then everything is fine. However, in my library I did not use any c++0x features, so I am reluctant to set std=c++0x option. So I search the head file that defines div_t and find it is defined in stdlib.h within the following MACRO:
__BEGIN_NAMESPACE_STD
typedef struct
{
int quot;
int rem;
} div_t;
....
....
__END_NAMESPACE_STD
It seems to me that if I can enable these macros I can build the library without enabling c++0x feature. So my question is what I can do in this situation.
By the way, I can build the library very well without enabling c++0x feature if only g++4.4 is installed in the linux machine. When I also install g++4.6 and make g++4.6 the default g++, then the compilation error began to occur. Even I changed the default g++ to g++4.4, the compilation error still exists if I do not enable c++0x feature.
The macros expand to namespace std { and } respectively if the code is pulled in through a C++ standard library header. This leads me to believe that you're not #including stdlib.h directly (which is good!).
Earlier versions of libstdc++ pulled symbols from C legacy headers into the global namespace even if the C++ versions of these headers (e.g. <cstdlib> instead of <stdlib.h>) were used; newer ones place them only in namespace std.
The cleanest way to fix this is to
#include <cstdlib>
in all translation units where the problem occurs and to use std::div instead of div. If you're lazy, you can also
#include <stdlib.h>
in all translation units that use div, but mixing C and C++ is always icky. Not terribad in this particular case, though.
Does fenv.h from C99 exists in C++11? Is there any other ways to use function like fesetround? Maybe boost?
gcc 4.7.2 compiles this code:
#include <cfenv>
int main() {}
http://liveworkspace.org/code/ffbd8e8a24633c7e74f7bcead3b1a287
Does fenv.h from C99 exists in C++11?
Yes it does.
Reference:
26.3 The floating-point environment [cfenv]
Standard C++11 26.3.1 Header <cfenv> synopsis [cfenv.syn]
Is there any other ways to use function like fesetround()? Maybe boost?
The function fesetround() is already provided by cfenv in C++11.
Also, fenv.h also exists in C++11 so as to provide backward compatability to c standard headers. It is covered under:
D.5 C standard library headers [depr.c.headers]
What is the difference between using fenv.h or cfenv?
Including cfenv imports the symbol names in std namespace and possibly in Global namespace.
Including fenv.h imports the symbol names in Global namespace and possibly in std namespace.
Yes, it does. cfenv appears to be the correct header, and it was just added in C++11.