The following program compiles correctly:
#include <algorithm>
int main(int argc, char *argv[]) {
return int(log(23.f));
}
(under g++ 4.9.2 with the flag -std=c++11)
The code uses the function log, which is defined on <cmath>. However, it does not include the header <cmath>, only the header <algorithm>. Why is it that g++ doesn't give any warnings, and compiles the code correctly?
According to the standard, some headers do include others. As an example, <cinttypes> includes <cstdint>. See the Includes section here. With respect to <algorithm>, there is no such statement as to which other headers it should include (see here). So, the conclusion is, <algorithm> is not required to include <cmath>, and your example code is not portable. It may fail to compile on other C++ implementations.
In the C++11 standard, [res.on.headers]/1 states that
A C++ header may include other C++ headers. A C++ header shall provide
the declarations and definitions that appear in its synopsis. A C++
header shown in its synopsis as including other C++ headers shall
provide the declarations and definitions that appear in the synopses
of those other headers.
Now consider [algorithms.general]/2:
Header <algorithm> synopsis
#include <initializer_list>
namespace std {
// ......
<cmath> isn't listed and clearly not included in <initializer_list>. Thus your program is not guaranteed to compile on a standard-conforming implementation. One should never rely on "implicit inclusion" - the general guideline is to include every header from which an entity is used.
Exceptions are e.g. <iostream> including <ostream>, which is guaranteed since C++11.
To answer your question:
Why is it that g++ doesn't give any warnings, and compiles the code correctly?
Because C++ implementations aren't required to and it's actually quite difficult to implement this warning given the way #include works. Attempts have been made, but there are problems that haven't been entirely addressed.
Moving to a different model can enable this kind of checking. However, in the interests of backwards compatibility and allowing the easiest possible transition the 'modularizations' of the standard library I've used happen to explicitly allow code that previously depended on indirect includes to continue to work.
You can see this, for example, in libc++'s module map; Those export * lines declare "any modules imported by this module are also exported." Which is to say, a module std.algorithm that imports a module std.cmath also exports, so anyone that imports std.algorithm also gets access to std.cmath.
For new code it would be very nice if these 'legacy exports' could be turned off, but for pre-existing large projects it is very nice to be able to just flip on -fmodules and have the project work with no changes.
Using clang's implementation of modules with libc++, and modifying the module map file to remove the non-portable, indirect include behavior, clang reports such errors like:
main.cpp:5:16: error: declaration of 'log' must be imported from module 'Darwin.C.math' before it is required
return int(log(23.f));
^
/usr/include/math.h:387:15: note: previous declaration is here
extern double log(double);
^
1 error generated.
libc++ <algorithm> doesn't include <cmath>, so I used <random> instead. Otherwise the source that produced the above is the same as what you show.
Related
I wrote a program that utilises INT_MIN. However, I did not include <climits> header file using the include directive. But my program still compiled without any errors or warnings. How? Did the compiler automatically include this header file?
Compiled the program using g++.
Edit: I only included the iostream library.
To have a less controversial example, consider this code:
#include <iostream>
int main() {
std::string s{"asd"};
std::cout << s;
}
It compiles without error here https://godbolt.org/z/fWbK4Yc5z.
If you use std::string you should include string. That does not imply that you can rely on an error when the include is missing. Standard library headers can include other headers. Here it happens that iostream apparently includes string. This is nothing to rely on. It may change with the next version of the compiler (I used gcc), and it can break on a different compiler.
The (inofficial) rule is: Include what you use. If you use std::string you should include string. If you use INT_MIN you should include climits.
Following piece of code does not work right on Alpine Linux:
#ifndef __cpp_lib_uncaught_exceptions
namespace std {
int uncaught_exceptions() noexcept {
return std::uncaught_exception();
}
}
#endif
Source
Error:
[ 89%] Linking CXX executable AdsLibTest.bin
/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../lib/libstdc++.a(eh_catch.o): in function `std::uncaught_exceptions()':
/home/buildozer/aports/main/gcc/src/gcc-11.2.1_git20220219/libstdc++-v3/libsupc++/eh_catch.cc:149: multiple definition of `std::uncaught_exceptions()'; CMakeFiles/AdsLibTest.bin.dir/main.cpp.o:main.cpp:(.text+0x8d0): first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [_deps/ads-build/AdsLibTest/CMakeFiles/AdsLibTest.bin.dir/build.make:98: _deps/ads-build/AdsLibTest/AdsLibTest.bin] Error 1
It looks like GCC does not provide __cpp_lib_uncaught_exceptions feature. Why this could happen?
I see a few issues with your code:
__cpp_lib_uncaught_exceptions is only documented to be defined (when applicable) if you've #include-ed <version> or <exception>; you've included neither. Add #include <exceptions> above that feature test somewhere, and it should work.
Your code as written will redefine uncaught_exceptions() in every compilation unit that includes it when the macro is not defined, because you made the definition in a header and did not make it inline, static or both, so every .cpp file including your header ends up getting its own exportable definition. Without the necessary headers included in your header, whether that feature test macro is defined will depend on whether each .cpp file includes <exception>/<version>, and whether it does so before or after including your header. If they aren't uniform, some files could get your header's definition, while others get the built-in definition.
Adding declarations to namespace std causes (with a few specific exceptions) undefined behavior. There is no reason that this should work, even if the compiler does correctly report that it doesn't provide std::uncaught_exceptions.
In particular, if the standard library implementation supported std::uncaught_exceptions and the file was compiled with language standard set to below C++17, then the feature test will claim that std::uncaught_exceptions is unsupported, but the standard library .a/.so may still provide the definition for it. This would cause a duplicate definition error.
As #ShadowRanger notes, there is also likely an inline missing on the function definition, because it may be included in multiple in multiple translation units.
Also, in order to use a feature test macro, it is necessary to include <version> (since C++20) or the header file corresponding to that features, e.g. in this case <exception>. Otherwise the macro is not defined and the feature check will always fail. It seems that the header is not including <exception>, but is including <stdexcept> though, which technically is not sufficient. However, practically, <stdexcept> is likely going to include <exception> and hence that would likely still work. For current libstdc++ this seems to be the case at least.
So, I would assume that your issue lies in the chosen compiler options, e.g. the language standard to compile for.
how do I compile a .c or .cpp file using GCC?
I need to include some standard libraries (fstream, string, iostream) - how do I do this?
For clarification, here:
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include"ocgenerator.h";
#include"structures.h";
#include"util.h";
#include"util2.h";
using namespace std;
(my .h files are in the same directory as the src file)
If I use the command:
gcc src.cpp -o src.o
I get a lot of errors: memcpy, atoi, atol, strncmp, etc, ... "are not declared in this scope". What should I add to the command?
edit: Or is it a scope thing, and do I have to add std:: to all those functions?
memcpy and strncmp are declared in <cstring>, atoi and atol in <cstdlib>. Just include these headers to bring in their declarations.
Side notes :
No semicolon after preprocessor directives, including #include "".
No using namespace std;, especially not in headers !
(Why is "using namespace std" considered bad practice?)
Since you're building a C++ project, don't forget to link with the standard library via -lstdc++, or use g++ which forwards it to the linker for you.
Note that with GCC you don't have to prefix standard C functions with std:: (as they are also declared in the global namespace), but you should anyway for your code to be standard-compliant.
The cplusplus site helps out. If you search for a specific function, on the top you will find the necessary references for the code to compile:
http://www.cplusplus.com/reference/cstdlib/atol/
You can even check in the URL. In this case, you need 'cstdlib'.
Regarding the compiler, there are several available, g++ is a good option.
I also suggest creating a makefile for automating the building process, because it becomes an headache when your codebase grows.
For any library function you use in your code, read the man page for that function to see which header declares it, and #include that header in any source file that uses the function.
For example, man memcpy shows the memcpy(3) man page (the (3) refers to section 3 of the manual; use man 3 memcpy to specify the section).
NAME
memcpy - copy memory area
SYNOPSIS
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
...
memcpy is part of the C standard library, and is declared in <string.h>. For C++ you can use <string.h>, but it's probably better to use <cstring>, which puts the function name in the std namespace. In general, each standard C header <foo.h> is duplicated as a C++ header <cfoo>.
I get a lot of errors: memcpy, atoi, atol, strncmp, etc,
memcpy and strncmp are declared in <cstring>. atoi and atol are <cstdlib> (or in <string.h> and <stdlib.h> if you're programming in C rather than in C++).
And be sure to use the g++ command, not the gcc command, to compile C++ source. They both invoke the same compiler (gcc compiles C++ code if the source file name ends in .cpp), but the g++ command adds some options that are needed for C++.
I think some headers need to be included to compile with gcc(4.9),
#include <algorithm> // for std::transform
#include <numeric> // for std::adjacent_difference
However, I found it's not necessary include them at all, I can still call
for example, the following functions
std::adjacent_difference (V1.begin(), V1.end(), V2.begin());
std::transform(V2.begin(), V2.end(), V3.begin(), V4.begin(), std::divides<double>());
Maybe I have misunderstood the mechanism of including header files...Any hint?
It is quite typical for a header to include other headers. The headers included by header x will be included in any file that includes x. That should be trivial to understand once you grasp what including a file in another means. In this case, one of the standard headers happened to be included in another.
Files included by headers can change between versions. If you don't include a required header, your program may break under another (version of) standard library even though it may appear to work in the current implementation. Of course, this applies to other libraries as well.
The C++ standard says the following in section 17.6.5.2 [res.on.headers]:
A C++ header may include other C++ headers.
For your question, this means a compiler can just act as if you included other C++ headers. In your example, the compiler is allowed to include the <numeric> header if you include <algorithm>, or vice versa.
But that's not the whole story. The standard also says:
A C++ header shown in its synopsis as including other C++ headers
shall provide the declarations and definitions that appear in the
synopses of those other headers.
And:
The C standard headers [...] shall include only their corresponding
C++ standard header [...]
(Note that I am quoting from the last free C++11 draft. The final version of the ISO standard is not free. See https://isocpp.org/std/the-standard.)
The <utility> header is an example of a C++ header which is guaranteed to include another. Its synopsis explitly includes <initializer_list>. Which means a conforming compiler must accept the following:
#include <utility>
// #include <initializer_list> // not needed
int main()
{
std::initializer_list<int> x = {};
}
For the C headers, in contrast, this means that the following must not compile:
#include <stdio.h>
int main()
{
std::cout << "\n"; // must not compile
}
What the standard says is surely confirmed by your implementation's documentation. For example, the documentation for Visual C++ 2013 says:
A C++ library header includes any other C++ library headers it needs
to define needed types. (Always include explicitly any C++ library
headers needed in a translation unit, however, lest you guess wrong
about its actual dependencies.) A Standard C header never includes
another standard header.
The advice given here is a good one; do not depend on automatic inclusion. Explicitly include everything you need.
Suppose i am editing some large C++ source file, and i add a few lines of code that happen to use auto_ptr, like in the following example.
#include <string>
// ... (much code here)
void do_stuff()
{
std::string str("hello world");
// ... (much code here too)
std::auto_ptr<int> dummy; // MY NEW CODE
// ...
}
This example compiles on gcc 3.4.4 (cygwin), because the standard header <string> happens to include the header <memory> needed for compilation of auto_ptr. However, this doesn't work on gcc 4.5.0 (mingw); they seem to have cleaned up their header files or something.
So, when i add code that uses auto_ptr, should i immediately go look whether the file contains #include <memory> at the beginning, as this answer implies? I never do it (i find it too annoying); i always rely on the compiler to check whether any #include is missing.
Is there any option that would not be disruptive to coding, and would ensure portability of my code?
Is there a C++ standard library implementation whose headers don't include each other more than is required?
If you use something in the standard library, you should include the header in which it is defined. That is the only portable option. That way you avoid the instance you cite where one header happens to include another in one version or compiler, but not another. auto_ptr is defined in <memory>, so if you use it, include that header.
[edit...]
In answer to your comment... Are you asking if the compiler can help detect when you use something from a standard header you didn't directly include? This would be helpful, but I think it's a little too much to ask. This would require the compiler to know which standard library headers contain which standard library definitions, and then check that you included the right ones for the definitions you used.
Determining exactly how a header was included is also a tall task. If you are using a standard library definition, then you must be including the header somehow. The compiler would have to tell whether you included the header yourself (possibly through headers of your own or a third-party library) or whether it came through another standard library header. (For instance, in your example, it would have to be able to tell the difference between <memory> being included via <string> or being included within your own code.)
It would have to handle different version of the standard library (e.g. C++03 vs C++0x) and different vendors. And what if those vendors of a third-party stdlib do not exactly follow the standard, then you could get bad warnings about which headers to include.
I'm only saying this to try to explain (with my limited compiler/stdlib knowledge) why I don't think compilers have this feature. I do agree, it would be helpful, but I think the cost outweighs the benefit.
The best way is to include the correct header in which the construct is defined.
and Include files should protect against multiple inclusion through the use of macros that "guard" the files
Generally header files have "include guards" surrounding them. The guards are formed by:
MyHeader.h:
#ifndef __MY_HEADER_H__
# define __MY_HEADER_H__
//body of MyHeader.h
#endif
So, you could include MyHeader.h as many times as you want:
#include "MyHeader.h"
#include "MyHeader.h"
#include "MyHeader.h"
#include "MyHeader.h"
And it won't cause any problems for the compiler (it will only ever be included once). Moreover you could include another file that includes "MyHeader.h", and the same rule would apply.
What this means is, if you ever want to use something that is defined in a header - include it! (Even if you think something else might include it, there is no reason not to be safe).