Easylogging 8.91 not compling without c++11 - c++

I want to use the library without C++11 but it won't compile for me:
(Theoretically it should as per documentation #http://easylogging.muflihun.com:
"For lower version of C++ (non-C++11), please consider using Easylogging++ v8.91. ")
error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
File structure:
./Main.cpp
./logger/easylogging++.h
Contents of Main.cpp:
#include "logger/easylogging++.h"
_INITIALIZE_EASYLOGGINGPP
using namespace std;
int main(int argc, char* argv[]) {
LINFO << "This is my first log";
return 0;
}
../src/logger/easylogging++.h: In function ‘std::string easyloggingpp::internal::threading::getCurrentThreadId()’:
../src/logger/easylogging++.h:691:16: error: ‘std::this_thread’ has not been declared
ss << std::this_thread::get_id();
Compiler: gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1), OS: Ubuntu 14.04 LTS

As T.C. suggested in the solution is to change this section of code at the top of easylogging++.h:
#if defined(__GNUC__)
# define _ELPP_GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define _ELPP_CXX0X 1
# elif (_ELPP_GCC_VERSION >= 40801)
# define _ELPP_CXX11 1
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
#endif // defined(__GNUC__)
Changing both _ELPP_CXX0X and _ELPP_CXX11 to 0 will fix the issue.

Related

-Wundef does not warn about an undefined symbol in front of #ifdef

Please consider the following code:
// program.cpp
#include <iostream>
int main() {
#ifdef LINUX
std::cout << "Linux\n";
#elif MAC
std::cout << "Mac\n";
#elif WINDOWS
std::cout << "Windows\n";
#elif BSD
std::cout << "BSD\n";
#else
std::cout << "Something else\n";
#endif
return 0;
}
If I compile it with both clang and gcc,
clang++ -Wundef -DBSD -o program program.cpp
# or
g++ -Wundef -DBSD -o program program.cpp
I will get warnings for not defining symbols MAC and WINDOWS, but no warning for the symbol LINUX:
program.cpp:6:7: warning: 'MAC' is not defined, evaluates to 0 [-Wundef]
#elif MAC
^
program.cpp:8:7: warning: 'WINDOWS' is not defined, evaluates to 0 [-Wundef]
#elif WINDOWS
^
2 warnings generated.
According to the gcc man page:
-Wundef
Warn if an undefined identifier is evaluated in an "#if" directive.
Such identifiers are replaced with zero.
It says in an #if directive. Is it because the LINUX is not inside that structure?
If that's the case, how can I tell compiler to emit warnings for the undefined symbol LINUX?
clang version 12.0.1
gcc (GCC) 11.1.0
Target: x86_64-pc-linux-gnu (artixlinux)
The reason is that your preprocessor code asks if LINUX is defined. But for MAC, WINDOWS and BSD you don’t bother checking whether the symbol is defined; instead, your code assumes it is defined and asks for its value.
Change your code to use #elif defined(…) instead of #elif … to fix the warning.

std::byte is not member of 'std'

I'm trying to learn new features/gimmicks of c++17, but then I got to std::byte and for some unknown reason I can't seem to be able to compile even most basic "hello world" type program with the type.
entire program:
#include <cstddef>
int main(int argc, char* argv[])
{
std::byte byte;
return 0;
}
compilation command:
g++ ./main.cpp
But the output is always:
./main.cpp: In function ‘int main(int, char**)’:
./main.cpp:4:10: error: ‘byte’ is not a member of ‘std’
std::byte byte;
I work on Ubuntu 18.04 with gcc 7.4.0. I have checked "/usr/include/c++/7.4.0/" and header file cstddef is there and byte seems to be defined.
I have also tried to use clang:
clang++ ./main.cpp
But the result was same. At this point I can only think that cstddef is corrupted/bugged. Are there any solutions to this?
As πάντα ῥεῖ pointed out in comment I was missing c++17 compile flag. Right compilation command:
g++ -std=c++17 ./main.cpp
If you use clang 5.0 (even with -std=c++17 flag) the same error occur.
In that case, to solve this you need to upgrade to clang 6.
A temporay and quick workaround is possible (but not recommanded since it plays with std namespace), it could be something like:
#if defined(__clang__) && __cplusplus >= 201703L && __clang_major__ < 6
// This is a minimal workaround for clang 5.0 with missing std::byte type
namespace std {
enum class byte : unsigned char {};
}
#endif

error : to_string was not declared in this scope

I am compiling the code on solaris 5.11.
G++ version is 4.8.2.
The same code works on Ubuntu but gives the error: 'to_string() was not declared in this scope' on solaris.
I went through many links and tried the following things:
Adding 'std::' before to_string(). This gives error - 'to_string is not a member of std'
Added 'std=c++11' or 'std=c++0x' while compilation.
Both the above things do not work.
Is there anything related to Solaris?
The actual code was very huge. So simulating the error in sample code below.
temp.cpp
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str;
int i = 10;
str = "john age is " + to_string(i);
cout << str;
return 0;
}
command: g++ temp.cpp -std=c++0x -o temp
For GCC 4.8.2 the to_string functions are defined conditionally, according to the following:
#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
The GLIBCXX_USE_C99 macro depends on a large number of C99 functions being supported by the OS, so presumably the necessary C99 library functions were not found when building GCC on Solaris. So the to_string definitions are absent.
In current versions of GCC the condition is more fine-grained, and checks whether the C99 functions are defined in C++98 mode and C++11, so that the absence of any C99 function doesn't disable everything:
#if __cplusplus >= 201103L
//...
#if _GLIBCXX_USE_C99_STDIO
It's not possible to backport these improvements to GCC 4.8, so you might need to update to at least GCC 6.
compile using std=c++11 as below
g++ -std=c++11 filename.cc
Note : your compiler must support c++11

Why don't complex-number literals work in clang?

When I run this code on ideone.com, it prints (2,3):
#include <iostream>
#include <complex>
int main() {
std::complex<double> val = 2 + 3i;
std::cout << val << std::endl;
return 0;
}
But when I use clang on macOS 10.11.6, I get no errors or warnings, but the output is (2,0):
$ clang --version
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.6.0
$ clang -lc++ test.cpp && ./a.out
(2,0)
What happened to the imaginary part? Am I doing something wrong?
I believe for this first example the compiler is using a GNU extension:
-fext-numeric-literals (C++ and Objective-C++ only)
Accept imaginary, fixed-point, or machine-defined literal number
suffixes as GNU extensions. When this option is turned off these
suffixes are treated as C++11 user-defined literal numeric suffixes.
This is on by default for all pre-C++11 dialects and all GNU dialects:
-std=c++98, -std=gnu++98, -std=gnu++11, -std=gnu++14. This option is off by default for ISO C++11 onwards (-std=c++11, ...).
When I run it with clang I get (are you using -Wall -pedantic? :)):
warning: imaginary constants are a GNU extension
[-Wgnu-imaginary-constant]
Either way, your code is not standard compliant. To use C++14 literals make the code:
#include <iostream>
#include <complex>
using namespace std::complex_literals;
int main() {
std::complex<double> val = 2.0 + 3i;
std::cout << val << std::endl;
return 0;
}
From the documentation:
These operators are declared in the namespace
std::literals::complex_literals, where both literals and
complex_literals are inline namespaces. Access to these operators can
be gained with using namespace std::literals, using namespace
std::complex_literals, and using namespace
std::literals::complex_literals.

File not found: using array class in C++

Here is the code: error shows up for line 8 of main.hpp .
//main.hpp
#ifndef MAIN_HPP // if main.hpp hasn't been included yet...
#define MAIN_HPP // #define this so the compiler knows it has been included
#include <array> // OFFENDING LINE 8
using std:array
class Quicksort {
public:
void sort(array);
};
#endif
This header is being used by this c++ file.
#include "main.hpp"
// this is just the start of a quicksort algorithm, base case only
void Quicksort::sort (array list) {
if (list.size == 1 || list.size == 0) {
return;
}
}
Why am I getting this error? I thought my C++ and g++ were fine. Any other reasons it might not be working?
I'm compiling with the command (on Mac, with newest X-Code): g++ version 4.2
g++ -Wall -c quicksort.cpp
When I use -std=c++11 it says:
unrecognized command line option "-std=c++11"
You need C++11 support to be able to include <array>. On GCC you would need to use the -std=c++0x flag (or -std=c++11 on the latest versions).
Furthermore, array lives in the std namespace, and you probably mean to pass a reference:
void sort(std::array&);
If your compiler does not support the relevant parts of C++11, you can use the version from TR1:
#include <tr1/array>
...
std::tr1::array<int, 5> a = ...;
You forgot to include -std=c++11 or -std=gnu++11 (-std=c++0x and -std=gnu++0x on older versions of GCC before 4.7.0), the latter which includes extensions. If that still doesn't work then you need a more recent version of GCC.