'Is there a way to bypass printf errors on different compilers?
I have the following line of code:
printf("\n\nTime taken for simulation: %ld milliseconds\n", duration.count() );
On my home machine, I get the error,
main.cpp:292:65: error: format specifies type 'long' but the argument has type 'std::__1::chrono::duration<long long, std::__1::ratio<1, 1000>>::rep' (aka 'long long') [-Werror,-Wformat]
This error is sorted out if I change %ld to %lld
I use g++ -std=c++14. Home compiler version is:
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: arm64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
On the linux cluster I operate, if run it with %lld, I get the following error,
main.cpp:229:83: error: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘std::chrono::duration<long int, std::ratio<1, 1000> >::rep {aka long int}’ [-Werror=format=]
I use g++ -std=c++14. Cluster compiler version is:
g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
if I change %lld to %ld, it is all good.
Is there a way I can print out duration.count(), where duration is defined as
auto duration = std::chrono::duration_cast<std::chrono::milliseconds> (stop-start);
where stop, start are variables of type specified by std::chrono::high_resolution_clock::now();.
Any advice you have would be appreciated.
Solution 1:[1]
A simple solution is to unconditionally convert to long long:
long long count = duration.count();
printf("%lld", count);
On the other hand, I recommend avoiding printf and its footguns.
Solution 2:[2]
(Assuming you need to use printf())
Couple your type definition with a specifier definition:
typedef my_duration_t std::chrono::duration<long long, std::milli>;
#define MY_DURATION_SPECIFIER "%lld"
and then you write:
auto duration = std::chrono::duration_cast<my_duration_t> (stop-start);
printf(
"\n\nTime taken for simulation: " MY_DURATION_SPECIFIER " milliseconds\n",
duration.count()
);
this (ugly) approach is the one used in stdint.h for the size-specific integer specifiers:
printf("Easy as " PRId64 "!\n", ((int64_t) 123));
see also here.
Solution 3:[3]
There are format macros for many types if you #include <cinttypes>, but it appears std::chrono::duration doesn't have a macro.
You might consider using string stream:
std::stringstream ss;
ss << duration.count();
printf("%s", ss.str().c_str());
Solution 4:[4]
(Assuming you need to use printf())
Use an intermediate std::stringstream:
std::stringstream ss;
ss << "\n\nTime taken for simulation: " << duration.count() << "\n";
printf("%s",ss.str().c_str());
// or instead of the last line: puts(ss.str().c_str());
Solution 5:[5]
Consider using std::cout in all cases.
With regards to speed difference between the two, consider using:
std::ios::sync_with_stdio(false);
at the beginning of your code. This only works if you replace all your printf/scanf (and the like) usage with their C++ alternatives.
Using this should make the speed difference go away.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | eerorika |
| Solution 2 | |
| Solution 3 | hyde |
| Solution 4 | einpoklum |
| Solution 5 | utnapistim |
