2

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.

Aurum
  • 21
  • 3
  • 2
    did you include other headers? – 463035818_is_not_an_ai Jan 17 '23 at 12:20
  • 4
    `iostream` will include other headers that will include other headers etc. – Ted Lyngmo Jan 17 '23 at 12:22
  • 15
    Any standard library is allowed to include any other standard library. But don't rely on that, always include what you use. – Yksisarvinen Jan 17 '23 at 12:22
  • It can be included in the precompiled header – Cy-4AH Jan 17 '23 at 12:24
  • 10
    Offtopic: But don't use INT_MIN in C++, use [std::numeric_limits::min()](https://en.cppreference.com/w/cpp/types/numeric_limits). INT_MIN is a macro and has no type. – Pepijn Kramer Jan 17 '23 at 12:24
  • 1
    @PepijnKramer actually [`INT_MIN` is typed](https://port70.net/%7Ensz/c/c99/n1256.html#5.2.4.2.1). That's why [`INT_MIN` must be defined as `-INT_MAX - 1` instead of `-SOMETHING`](https://stackoverflow.com/q/26003893/995714). But yes you should prefer `std::numeric_limits` in C++ – phuclv Jan 17 '23 at 12:56
  • @Pepijn Krame in theory - yes bad idea, In practice - numeric limits may not work as you expect with different compilers, or even same compiler but deferent operating systestems. INT_MIN - will work everywhere, and exactly as expected. – Victor Gubin Jan 17 '23 at 12:59
  • 2
    @VictorGubin sounds like FUD, what actual C++ compiler in practice you mean? The std::numeric_limits is there since C++98. – Öö Tiib Jan 17 '23 at 13:08
  • @phuvlc no there is not type, `#define INT_MAX 2147483647, #define INT_MIN (-2147483647 - 1)` it is a macro, a typeless number that the preprocessor will just replace. – Pepijn Kramer Jan 17 '23 at 13:17
  • @VictorGubin I would be interested in an example. The thing with std::limits is that they play nice with class templates and the macros will not. And these things matter in libraries. – Pepijn Kramer Jan 17 '23 at 13:19
  • 2
    @PepijnKramer A numeric literal always has a type. You can do `decltype(INT_MAX)` and get `int`. – HolyBlackCat Jan 17 '23 at 13:48
  • @HolyBlackCat Now you mention it, _I8_MAX 127i8 indeed has the type i8... totally missed that all this time. – Pepijn Kramer Jan 17 '23 at 13:49
  • One of my hobby projects was what I called **deader files**. The deader files were header files that would compile, but not link. They only provided symbols required, and no more. They did not include any other header file (unless required by the standard). They did not pollute the global namespace. If you missed a standard header file, the code would not compile, because the deader files did not provide implicit dependencies to other standard header (deader) files. – Eljay Jan 17 '23 at 13:58
  • @Öö Tiib Try contexpr and you'll know, especially with some MS VC++ older version (BTW new version of VC++ is the only compiler fully support STD 2017). Off cause min/max/digit10 etc works for run-time only code with exactly same way as macros. – Victor Gubin Jan 17 '23 at 14:03
  • @PepijnKramer no [`2147483647` is an `int` literal](https://stackoverflow.com/a/8108715/995714). In C++ it's even easier to check, just print `typeid(t).name()` – phuclv Jan 17 '23 at 14:57
  • @VictorGubin Please be precise what version of VS does not support std::numeric_limits? Those that compiled for 16 bit subsystem 30 years ago? But Windows does not have that subsystem anymore. Why to use such compilers? – Öö Tiib Jan 17 '23 at 14:57
  • 1
    @phuclv Yes I learned something today. It can be checked at compile time too : `static_assert(std::is_same_v);`. As said just stupid I missed this all those years. – Pepijn Kramer Jan 17 '23 at 14:59

1 Answers1

0

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.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185