scanf int8_t corrupts stack - c++

How to scanf int8_t and other types without this error. I used "cinttypes" to get constants of patterns but that didn't help.
#include <cstdio>
#include <cstdint>
#include <cinttypes>
int main()
{
int8_t var;
scanf("%" SCNi8, &var);
printf("%" PRIi8 "\n", var);
return 0;
}
P.S. This error occures only in Debug, when building in Release it's OK.
P.P.S. Output is:
1>------ Build started: Project: SCANF_PROBLEM, Configuration: Debug Win32 ------
1> SCANF_PROBLEM.cpp
1>d:\study\scanf_problem\scanf_problem\scanf_problem.cpp(11): warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> d:\visual studio\vc\include\stdio.h(283) : see declaration of 'scanf'
1> SCANF_PROBLEM.vcxproj -> D:\Study\SCANF_PROBLEM\Debug\SCANF_PROBLEM.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Even in C99, those extended integer types aren't required to exist, unless the documentation says they exist, more on that later... Even if those extended integer types do exist they're not required to have scanf format specifiers. See n1256 section 7.8.1p6 for this quote:
For each type that the implementation provides in <stdint.h>, the corresponding
fprintf macros shall be defined and the corresponding fscanf macros shall be
defined unless the implementation does not have a suitable fscanf length modifier for
the type.
As for C++, well... C++11 delegates that <cstdint> shall essentially be a wrapper for C99s <stdint.h>, and the functions it refers to be wrappers for the C99 equivalents.
Here's the kicker: Microsoft has never cared all that much about C99, to the extent that they're willing to document "N/A" for extended integer support, for example.
Make sure your compiler is configured to compile as C99 or later, or C++11 or later, and link to a C99-or-later-compliant standard library. SCNi8 may exist in the headers, but if scanf doesn't support it (which it won't, prior to C99/C++11 compliance) then you won't have any luck with it... and of course, make sure your standard library documents support for the implementation-defined features you intend to use.
Protip: If your filename ends in .c, Microsoft Visual Studio will attempt to compile your code as C89. That's probably not going to be helpful. MSVC++'s C99-compliance in terms of the standard library isn't too great even when you tell it to compile as C++11. You should probably learn how to determine which compiler/library versions you're using... while you're learning how to compile using the command line.
Protip #2: You can use LLVM/Clang in Visual Studio. Make sure you link to a C99-compliant standard library (e.g. not Microsoft).
Protip #3: You might want to change SCNi8 for PRIi8 when using printf...
Protip #4: See footnote 191 for this quote:
C++ implementations should define these macros only when __STDC_FORMAT_MACROS is defined
before <inttypes.h> is included.

You have run into a bug of Microsoft's C/C++ runtime library, cf. http://mfctips.com/tag/format/ or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63417 (which reports this bug for gcc under mingw, which links against the Microsft libs).
"%hhd" just doesn't work; you must program around it (which isn't too hard, but sad).
I am not aware of a bug report to MS (i.e., I did not see anything when I tried to google it).

Related

VSCode C++ Intellisense can't discern C++20 features

I try to run codes like
#include <string>
#include <iostream>
int main() {
std::string str = "This is a string";
std::cout << str.starts_with("name");
}
But intellisense will give out an error
"std::__cxx11::basic_string<char, std::char_traits,
std::allocator>" has no member "starts_with" C/C++(135) [6,9]
And It still can be build and produce a correct result.
Also it can find implementation in header file.
But the macro __cplusplus is defined as 201703L
I've already added a command -std=c++20 when building, why this happened?
Compiler: minGW 11.2 compiled by msys2
Assuming you are using Microsoft's C/C++ extension, you must configure the extension to use C++ 20 standard for intellisense.
The easiest way to do this is to add the line "C_Cpp.default.cppStandard": "c++20" to your settings.json file. You can also find the setting in the GUI under the name "Cpp Standard". Selecting c++20 from its dropdown will achieve the same result.
Note that this setting is, by default, set as a global user defaults. You can configure it per-workspace by selecting the Workspace tab in the settings GUI and changing that Cpp Standard dropdown to c++20.
As for why adding the -std=c++20 flag didn't work: -std=c++20 just tells your compiler which standard to use to build your code. 'Intellisense' does not receive this flag because it is a separate tool from the compiler and is therefore not required to support all the standards the compiler supports. It may support less even, although Intellisense tools usually support as current a standard as possible. Therefore the language standard for Intellisense must be configured separately from the compiler (in this case).
Final Note: After changing the setting, try closing and re-opening VS Code. In my experience changing the language standard setting can cause some weirdness to happen. Closing and re-opening VS Code seems to ensure the setting changes take full effect.

gRPC auth_context.h using std::iterator produces deprecated warning with latest VC++ compiler

Compiling one of my projects that uses gRPC with the latest Visual Studio 2019 16.5 preview 2 compiler gives rise to this warning:
1>D:\...\grpcpp\impl\codegen\security\auth_context.h(38,19): warning C4996: 'std::iterator<std::input_iterator_tag,const grpc::AuthProperty,ptrdiff_t,const grpc::AuthProperty *,const grpc::AuthProperty &>': warning STL4015: The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. (The <iterator> header is NOT deprecated.) The C++ Standard has never required user-defined iterators to derive from std::iterator. To fix this warning, stop deriving from std::iterator and start providing publicly accessible typedefs named iterator_category, value_type, difference_type, pointer, and reference. Note that value_type is required to be non-const, even for constant iterators. You can define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.
Before submitting a bug report, I thought I've check here if the gRPC developers are already aware of this?
gRPC is currently dependant on Absel that is reliant on C++11. You should avoid using two different C++ standards in your applications to avoid template incompatibilities. There is a longer discussion on Absel C++11 vs C++17 versions here: https://github.com/abseil/abseil-cpp/issues/259.
You can check out the Absel pages for more details at https://github.com/abseil/abseil-cpp.
The position that gRPC doesn't support C++17 is a little surprising. I might be missing it, but I don't see any mention on the main grpc page that anything beyond C++11 isn't supported. The only support matrix I was able to find was: https://grpc.io/docs/#official-support
In general both protobuf and gRPC usage will cause a slew of warnings in Visual Studio, unrelated to this error. For generated cc files, suppressing warnings 4267, 4996, and 4244 is helpful.
For this C++17 warning/error, since the issue is in a header, you'll hit the issue on your own, non-generated cpp files. You don't want to disable such warnings/errors on every file that uses the header, because then you'll mask your own issues. I currently work around by creating grpcpp.suppress_errors.h:
#pragma once
#pragma warning ( push )
#pragma warning( disable : 4996)
#include <grpcpp/grpcpp.h>
#pragma warning ( pop )
Then instead of including <grpcpp/grpcpp.h>, include grpcc.suppress_errors.h . It's a bit silly, but it will keep your own code clean from suppressions.
aggieNick02's answer didn't fix it for me. But I could could manage to suppress the errors in Visual Studio like so:
I added _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS; to the preprocessor definitions.
Not as optimal as aggieNick02's answer, but at least this kept me going.
I got grpc from vcpkg, if that info helps somebody:
1.37.0 3
dc35791a568aacf855355bcfcdff978ec22e69d3
2021-07-27
abseil (2021-03-24), c-ares (1.17.1), grpc (1.37.0), openssl (1.1.1k), protobuf (3.15.8), protobuf (3.15.8), re2 (2020-10-01), upb
(2020-12-19), zlib (1.2.11)
gRPC does not currently support C++17. We're currently using C++11. You should probably use whatever flags are necessary to have your compiler enforce C++11 semantics.

(MSVC 2017 /WALL & /WX) Including Iostream Produces 800 Warnings

Reviewing material for an optimized C++ course next quarter. The professor for this course is enforcing /WALL and /WX for our project properties. The problem I'm having is that including the Iostream library produces over 800 warnings. Here's the code I'm attempting to run:
#include "pch.h"
#include <iostream>
int main() {
std::cout << "Hello World";
return(0);
}
A few of the warnings that I'm receiving includes:
C4514 'abs': unreferenced inline function has been removed
C4774 'sprintf_s': format string in argument 3 is not a string literal
C4820 'std::basic_ios ...': '7' bytes of padding added after...
Before asking Stack I emailed the Prof to ask about the warnings and was told:
You should be including iostream
If you get 100 warnings you included a header that's not needed
Is there something I'm missing? I know I wouldn't be able to edit source files for iostream as that's not portable coding. I looked around to see if I could explicitly include functions such as cout, cin, etc. Yet, I don't feel like this is the correct solution.
Edit:
A user requested an example of a more explicit warning message in case there was something missing in there. Here are a few:
C415 'abs': referenced inline function has been removed (Project: Hello World) (File: stdlib.h)
C4710 'int sprintf_s(char *const....: function not inlined. (Project: Hello World) (File: stdio.h)
The professor is using GCC through Visual Studio and our settings are pulled from a repository as premade projects.
Your professor is, quite simply, wrong.
This has nothing to do with "including a header that's not needed" (why would that generate warnings?), but with using /WALL, which reveals some flaws in the stdlib implementation there!
This switch is not recommended; quoting James McNellis who gets it bang-on under the above referenced question:
/Wall enables many warnings that, while potentially useful sometimes, are not useful most of the time. /Wall in Visual C++ does not mean the same thing as -Wall on g++ (really, g++ "has /Wall wrong," since it doesn't actually enable all warnings). In any case, in Visual C++, all of the commonly important and useful warnings are enabled by /W4.
I would use /W4 in Visual Studio (and -Wall -Wextra in GCC).
Obviously I can't help you to persuade your professor of this, other than to suggest saying something along the lines of "I asked on Stack Overflow and found out that this is due to /Wall being too strict and generating warnings on Visual Studio's own headers. They suggest we use /W4 instead. . What do you think?"
It is true that you need to #include <iostream>, and it is true that you should never modify the provided standard headers. Also, don't forget to stream a '\n' to end your output line!

Does C++17 provide a cross-platform scheme to record compiler version and options like Fortran?

Question
Modern Fortran offers a few cross-platform mechanisms to record the compiler version and settings used to build an application. What methods does C++17 have to capture this information? The book by Horton and Van Weert, Beginning C++17, does not appear to address this question.
The Fortran tools are surveyed below.
1. Access to compiler versions and options
The iso_fortran_env in Fortran provides a standard way to access the compiler version and settings used to compile a code. A sample snippet follows.
Code sample
program check_compiler
use, intrinsic :: iso_fortran_env, only : compiler_options, compiler_version
implicit none
write ( *, 100 ) "compiler version = ", compiler_version ()
write ( *, 100 ) "compiler options = ", trim ( compiler_options () )
100 format ( A, A, / )
stop "normal termination . . ."
end program check_compiler
Sample output
$ gfortran -o check_compiler check_compiler.f08
$ ./check_compiler
compiler version = GCC version 8.0.0 20170604 (experimental)
compiler options = -fPIC -mmacosx-version-min=10.12.7 -mtune=core2
STOP normal termination . . .
2. Probing and interacting with host OS
Fortran commands like execute_command_line, get_command, and get_environment_variable offer another route to record information at compile time.
What methods does C++17 have to capture this information?
None. The C++ standard does not even recognize the concept of "compiler" or "options"; there is merely the "implementation".
Furthermore, it would not really make sense, as different C++ files linked into the same program can be compiled with different options. And I'm not just talking about DLL/SOs; you can in theory statically link files that were compiled with different options or even different compiler versions.
Different compilers have ways to specify what version they are through macros. But each one has its own way to report this.
Searching the C++20 standard draft, which is available in GitHub, I find no results for closely-localted "compiler" and "version", nor have I found something like this looking at the text of the standard.
C++20 is at this time still very close to C++17, and certainly such a mechanism has not been removed, so I think it's pretty safe to say that there's no such thing in C++20.
Each compiler injects their own preproxessor tokens indicating itmwas compiled by them, and what version. These tokens are cross platform on compilers that compile on and to kore than one platdorm, such as icc, gcx and clang.
There are now standard defined ways to detect the existence of some srd header files. Boost has extensive headers that decode compiler capabilities based of a myriad of techniques.
__cplusplus in theory is defined to the standard version, but compilers lie.
The language standard specifies macros __cplusplus that encode the version of the standard that the compiler claims to support. It expands to 201703L on a C++17 compiler, 201710L on a C++14 compiler, and so on. It might also define _STDC and _STDC_VERSION. Beyond that, everything is a vendor-specific extension that you should look up in your compiler's manual.
Some but not all compilers, including GCC and Clang, predefine a macro named __VERSION__ that expands to a string describing the compiler version. You can check for this with #ifdef. Beyond that, many compilers contain macros that expand to version numbers, which you can stringify and concatenate. However, be aware that some compilers treat these as compatibility tests, and will claim to be a different compiler if you ask. In addition to its own version numbers, Clang defines __GNUC__, __GNUC_VERSION__ and __GNUC_PATCHLEVEL__ to indicate its compatibility with GCC, and the Windows version will also define _MSC_VER, _MSC_FULL_VER and so on in its Microsoft-compatiblity mode.
You could therefore create a complicated set of nested #elif blocks to recognize various compilers' version macros, but it could never be complete or forward-compatible.

-O1/2/3 with -std=c++1y/11/98 - If <cmath> is included i'm getting error: '_hypot' was not declared in this scope

I've just updated MinGW using mingw-get-setup and i'm unable to build anyting that contains <cmath> header if I use anything larger than -O0 with -std=c++1y. (I also tried c++11 and c++98) I'm getting errors like this one:
g++.exe -pedantic-errors -pedantic -Wextra -Wall -std=c++1y -O3 -c Z:\Projects\C++\L6\src\events.cpp -o obj\src\events.o
In file included from z:\lander\mingw\lib\gcc\mingw32\4.8.1\include\c++\cmath:44:0,
from Z:\Projects\C++\L6\src\utils.h:4,
from Z:\Projects\C++\L6\src\events.cpp:10:
z:\lander\mingw\include\math.h: In function 'float hypotf(float, float)':
z:\lander\mingw\include\math.h:635:30: error: '_hypot' was not declared in this scope
{ return (float)(_hypot (x, y)); }
Is something wrong on my side?
Or version at mingw repo is bugged? And if so, is there any quick fix for this header?
To avoid any further speculation, and downright bad suggestions such as using #if 0, let me give an authoritative answer, from the perspective of a MinGW project contributor.
Yes, the MinGW.org implementation of include/math.h does have a bug in its inline implementation of hypotf (float, float); the bug is triggered when compiling C++, with the affected header included (as it is when cmath is included), and any compiler option which causes __STRICT_ANSI__ to become defined is specified, (as is the case for those -std=c... options noted by the OP). The appropriate solution is not to occlude part of the math.h file, with #if 0 or otherwise, but to correct the broken inline implementation of hypotf (float, float); simply removing the spurious leading underscore from the inline reference to _hypot (float, float), where its return value is cast to the float return type should suffice.
Alternatively, substituting an equivalent -std=gnu... for -std=c... in the compiler options should circumvent the bug, and may offer a suitable workaround.
FWIW, I'm not entirely happy with MinGW.org's current implementation of hypotl (long double, long double) either; correcting both issues is on my punch list for the next release of the MinGW runtime, but ATM, I have little time to devote to preparing this.
Update
This bug is no longer present in the current release of the MinGW.org runtime library (currently mingwrt-3.22.4, but fixed since release 3.22). If you are using anything older than this, (including any of the critically broken 4.x releases), you should upgrade.
As noted by Keith, this is a bug in the MinGW.org header.
As an alternative to editing the MinGW.org header, you can use MinGW-w64, which provides everything MinGW.org provides, and a whole lot more.
For a list of differences between the runtimes, see this wiki page.
MinGW uses gcc and the Microsoft runtime library. Microsoft's implementation support C90, but its support for later versions of the C standard (C99 and C11) is very poor.
The hypot function (along with hypotf and hypotl) was added in C99.
If you're getting this error with a program that calls hypot, such as:
#include <cmath>
int main() {
std::cout << std::hypot(3.0, 4.0)) << '\n';
}
then it's just a limitation of the Microsoft runtime library, and therefore of MinGW. If it occurs with any program that has #include <cmath>, then it's a bug, perhaps a configuration error, in MinGW.