elfutils compilation error implicit-function-declaration - c++

I downloaded elfutils 0.170 and 0.169, but can't use gcc to compile either of them because of implicit-function-declaration. I can't find any place in elfutils makefile which specifies -Werror or -Werror=implicit-function-declaration. Any idea to fix this compilation error?
https://sourceware.org/elfutils/ftp/0.170/
My steps
1: bzip2 -d elfutils-0.170.tar.bz2
2: tar -xvf elfutils-0.170.tar
3: ./configure
4: make
Then below errors show up.
elf_compress_gnu.c: In function 'elf_compress_gnu':
elf_compress_gnu.c:114:28: error: implicit declaration of function 'htobe64' [-Werror=implicit-function-declaration]
uint64_t be64_size = htobe64 (orig_size);
^
elf_compress_gnu.c:163:15: error: implicit declaration of function 'be64toh' [-Werror=implicit-function-declaration]
gsize = be64toh (gsize);
^
cc1: all warnings being treated as errors

elfutils incorrectly uses htobe64, which is not in any standard and only available in glibc and a subset of the BSDs.
Since you use GCC, you can use Ulf Hermann's patch to work around this issue:
Add replacement endian.h and byteswap.h to libgnu
It adds an implementation of htobe64 based on GCC built-in functions, so it is available when GCC is used as the compiler, independently of what the C library provides.

Related

Ignore [clang-diagnostic-error] clang-tidy caused by 3rd party headers

I am using clang-tidy as a "linter" tool in development. I started to integrate 3rd party software into my code and when I include their header files using:
-I/path/to/include
tons of errors are generated, I haven't even #include the headers yet.
error: too many errors emitted, stopping now [clang-diagnostic-error]
...
/path/to/include/wchar.h:81:1: error: unknown type name 'wint_t' [clang-diagnostic-error]
wint_t fgetwc(FILE *__stream);
^
/path/to/include/wchar.h:81:15: error: unknown type name 'FILE' [clang-diagnostic-error]
wint_t fgetwc(FILE *__stream);
^
...
I compile my program using:
/usr/bin/clang-tidy-4.0 /path/to/main.cpp -checks=-*,cppcoreguidelines* -- -lang-c++ -I/path/to/include -std=gnu++11 -Wall -Werror -O0 -g -D<define variables>
It seems that these "clang-diagnostic-errors" do not stop compilation, as it continues to compile and runs fine. Is there a flag to turn this error off/suppress it? I do not want to see it since I did not write these header files.
If I get rid of the argument -I/path/to/include everything compiles fine with no errors.
There is no way to ignore clang-diagnostic-error since it's basically a compiler error.
For clang-tidy to work the analyzed code needs to be compile-able by the clang backend to generate an AST(Abstract syntax tree).
The problem is you are including headers that cannot be compiled by clang (I'm guessing windows headers intended for MSVC).
I'm not sure if this would not break something later, so just at your own risk. I managed to "solve" this (because it was just a matter of having an error on the Problems list) on VSCode:
"C_Cpp.codeAnalysis.clangTidy.args": [
"--extra-arg=-ferror-limit=1"
]
This makes clang-tidy tell the compiler to throw just one error and give up. So clang-tidy will parse whatever is left.
I know was for VSCode, but the argument can be used in other IDEs.

Compiling bfx-cpp-api - Byte datatype undeclared

So I am looking to compile this project https://github.com/MMquant/bfx-cpp-api using the example code. I have included the cryptopp file that was suggested in the read me. It is found here: https://github.com/weidai11/cryptopp.
I am using Ubutnu version 17.10 and the GNU compiler.
Here's how I am compiling:
g++ example.cpp BitfinexAPI.cpp BitfinexAPI.hpp -Icryptopp -I. -o a -w -std=c++17
It seems strange that BitFinex would support broken code so I am fairly sure that the issue must be something that I am doing.
The errors I am getting are related to line 936 where the datatype 'byte' is not declared. My prediction is that I am missing a header file somewhere but any help would be appreciated.
$ g++ example.cpp BitfinexAPI.cpp BitfinexAPI.hpp -Icryptopp -I. -o a -w -std=c++17
BitfinexAPI.cpp: In static member function ‘static int BitfinexAPI::getBase64(const string&, std::__cxx11::string&)’:
BitfinexAPI.cpp:936:5: error: ‘byte’ was not declared in this scope
byte buffer[1024] = {};
^~~~
BitfinexAPI.cpp:936:5: note: suggested alternative:
In file included from ../cryptopp/seckey.h:9:0,
from ../cryptopp/hmac.h:9,
from BitfinexAPI.cpp:37:
../cryptopp/config.h:222:23: note: ‘CryptoPP::byte’
typedef unsigned char byte;
^~~~
BitfinexAPI.cpp:940:9: error: ‘buffer’ was not declared in this scope
buffer[i] = content[i];
^~~~~~
BitfinexAPI.cpp:940:9: note: suggested alternative: ‘setbuffer’
buffer[i] = content[i];
^~~~~~
setbuffer
BitfinexAPI.cpp:943:21: error: ‘buffer’ was not declared in this scope
StringSource ss(buffer, content.length(), true, new Base64Encoder( new StringSink(encoded), false));
^~~~~~
BitfinexAPI.cpp:943:21: note: suggested alternative: ‘setbuffer’
StringSource ss(buffer, content.length(), true, new Base64Encoder( new StringSink(encoded), false));
^~~~~~
setbuffer
BitfinexAPI.cpp: In static member function ‘static int BitfinexAPI::getHmacSha384(const string&, const string&, std::__cxx11::string&)’:
BitfinexAPI.cpp:963:33: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]
SecByteBlock byteKey((const byte*)key.data(), key.size());
^~~~
BitfinexAPI.cpp:963:27: error: expected primary-expression before ‘const’
SecByteBlock byteKey((const byte*)key.data(), key.size());
^~~~~
BitfinexAPI.cpp:963:27: error: expected ‘)’ before ‘const’
Here's how I am compiling:
g++ example.cpp BitfinexAPI.cpp BitfinexAPI.hpp -Icryptopp -I. -o a -w -std=c++17
It seems strange that BitFinex would support broken code so I am
fairly sure that the issue must be something that I am doing.
The errors I am getting are related to line 936 where the datatype
'byte' is not declared. My prediction is that I am missing a header
file somewhere but any help would be appreciated.
#kabanus identified the problem.
Crypto++ used to provide a byte in the global C++ namespace. It was there for two reasons. First, it was a convenience item on Linux. You could use byte instead of CryptoPP::byte. Second, it avoided compiler errors on Windows. Microsoft SDK's provide a byte in the global namespace, and if we put a byte at CryptoPP::byte then compile errors resulted from ambiguous definitions.
C++17 came along and offered a std::byte; see P0298R0, A byte type definition. The global Crypto++ byte broke Linux when folks used a using namespace std. And it completely broke Microsoft because Microsoft SDK's provides a global byte. Ironically, the authors of P0298R0 work for Microsoft.
Crypto++ placing a byte in the global namespace was a C++ No-No. We got away with it for years, but it jumped up and bit us in C++17. We moved it into our namespace where it belongs. The check-in occurred at Commit 00f9818b5d8e, which happened after 5.6.5 was released and prior to 6.0 release.
Looking at the source for BitfinexAPI.cpp, this is probably the solution... open BitfinexAPI.cpp, and add the following at the top of the file:
// CRYPTOPP_NO_GLOBAL_BYTE signals byte is at CryptoPP::byte
#if defined(CRYPTOPP_NO_GLOBAL_BYTE)
using CryptoPP::byte;
#endif
Also see std::byte on the Crypto++ wiki. We took the time to document it because of all the problems std::byte, Microsoft's global byte and our byte definitions are going to cause.
Related, you don't need to specify the C++ header on the command line. The compile error is due to the changes detailed above. All you need is:
g++ -std=c++17 example.cpp BitfinexAPI.cpp -I. ./cryptopp/libcryptopp.a -o example.exe
This assumes a directory structure of:
- bfx-api/
|
+- cryptopp/
The cryptopp/libcryptopp.a is a convenient way to sidestep those stupid Linux path problems that have existed for years. You link against the static archive which means you don't need a library at runtime.
Now open in the BFX issue tracker: Crypto++ byte change at Crypto++ 6.0. It should help the project engineer around the changes.
A bit tricky but I (think?) found it. byte is defined in the cryptopp code at:
https://github.com/weidai11/cryptopp/blob/master/config.h
line 222. So I'm guessing the config.h on your system is non-existent, probably because you didn't properly install the header. A common problem is having the library
sudo apt-get install libcrypto++
but missing the developer files (specifically the headers)
sudo apt-get install libcrypto++-dev
I'm not 100% about the package names (Debian user), should be close though.
Good catch from JTejedor:
Seems like the crypto guys placed a namespace around their definitions so as to not conflict with std::byte. You may want to add a CryptoPP:: to the byte definition in bfx (line 936), and if that works open a bug to the guys over there (or request a pull).

G++ ignores _Pragma diagnostic ignored

I am trying to disable g++ warnings in code expanded from macros. By my understanding, _Pragma should follow macro usage and this should not trigger Wparentheses when being compiled with g++:
#include <stdio.h>
#define TEST(expr) \
int a = 1; \
_Pragma( "GCC diagnostic push" ) \
_Pragma( "GCC diagnostic ignored \"-Wparentheses\"" ) \
if (a <= expr) { \
printf("filler\n"); \
} \
_Pragma( "GCC diagnostic pop" )
int main(){
int b = 2, c = 3;
TEST(b == c);
}
When I compile this with g++, I get Wparentheses warning, which I am trying to disable.
xarn#DESKTOP-B2A3CNC:/mnt/c/ubuntu$ g++ -Wall -Wextra test3.c
test3.c: In function ‘int main()’:
test3.c:8:11: warning: suggest parentheses around comparison in operand of ‘==’ [-Wparentheses]
if (a <= expr) { \
^
test3.c:15:5: note: in expansion of macro ‘TEST’
TEST(b == c);
^
However it works as expected when using gcc:
xarn#DESKTOP-B2A3CNC:/mnt/c/ubuntu$ gcc -Wall -Wextra test3.c
test3.c: In function ‘main’:
test3.c:16:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
I am using g++ version 4.8.5.
There are long-standing bugs in g++ handling of _Pragmas, that are not present when using the gcc front-end. The only solution is to either go forward to a sufficiently modern version of g++ (IIRC 6+), or to disable the warning for the entire TU.
Xarn's answer was very helpful in working out why we were hitting the same issues with our macros when compiling with g++ < 9.0, but fortunately I'm stubborn and don't take "the only solution" for an answer. Some more digging revealed that there is a workaround for affected versions of GCC.
One of the original 2012 reports for this issue at GNU's bugzilla included an offhand mention from the reporter, that _Pragma() would be processed as expected if they added either -save-temps or -no-integrated-cpp to the compile command.
Turns out, either of those options cause g++ NOT to run in its default streamlined mode, which folds the preprocessing and compiling stages together into a single pass. From the man page for g++ 9.1.1:
-no-integrated-cpp
Perform preprocessing as a separate pass before compilation. By
default, GCC performs preprocessing as an integrated part of input
tokenization and parsing. If this option is provided, the
appropriate language front end (cc1, cc1plus, or cc1obj for C, C++,
and Objective-C, respectively) is instead invoked twice, once for
preprocessing only and once for actual compilation of the
preprocessed input. This option may be useful in conjunction with
the -B or -wrapper options to specify an alternate preprocessor or
perform additional processing of the program source between normal
preprocessing and compilation.
Which means that adding -no-integrated-cpp does indeed work around the _Pragma() bug in every affected version of GCC we've tested — so far that's 5.4, 7.3, and I believe 8.1 — but otherwise has no effect on the final results of the build. (One can deduce from this that the _Pragma() bug was introduced with and by that single-pass streamlining.)
The only real tradeoff is that compilation is indeed a bit slower, if you build with that option enabled. While that's certainly worth it when your GCC is one of the affected versions, we're using a conditional in our CMake build setup to ensure -no-integrated-cpp is only set when necessary:
#### Work around a GCC < 9 bug with handling of _Pragma() in macros
#### See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
if ((${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") AND
(${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS "9.0.0"))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-integrated-cpp")
endif()
(Substitute appropriately modern calls to target_compile_options() for the ugly brute-forcing of CMAKE_CXX_FLAGS, if your CMake setup is better than ours.)
Typically you use warning suppression only to deal with unavoidable warning coming from third-party code so they won't clutter compilation logs. In your case it would be better to
1) use regular function because macros are evil
2) deal with warning by adding round brackets around potentially broken expression
if (a <= (expr)) {

Suppress warnings from boost includes

I have a c++ application (built under linux with g++ 4.8.3, boost 1.54) that spouts a lot of warnings about boost. Warnings include:
/usr/local/include/boost/math/constants/constants.hpp:314:3: warning: non-standard suffix on floating constant [-Wpedantic]
BOOST_DEFINE_MATH_CONSTANT(rayleigh_skewness, 6.311106578189371381918993515442277798e-01, "6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264e-01")
/usr/local/include/boost/concept/detail/general.hpp:71:20: warning: typedef 'boost_concept_check228' locally defined but not used [-Wunused-local-typedefs]
BOOST_PP_CAT(boost_concept_check,__LINE__)
...
There are so many different ones . It looks like from here that you can suppress particular typedef warnings: https://svn.boost.org/trac/boost/ticket/7242
But I would like to be able to suppress all of these warnings. Any suggestions?
As the commenter T.C. suggests, warnings are suppressed for system headers in gcc. There are (at least) two ways of adding additional system include paths to your gcc build:
-isystem command line option, and
*_INCLUDE_PATH environment variables (where '*' is C, CPLUS, or OBJC).
These mechanisms also work for clang.

gcc TemplateClass<::GlobalSymbol> error on <::

For some reason gcc does not like when template parameter is a global namespace symbol, i.e.
TemplateClass<::GlobalSymbol>
It works when I do
TemplateClass< ::GlobalSymbol>
That is, gcc does not like to see <::
Is it possible to prevent without modifying sources (which are autogenerated)?
UPD: I don't want to modify sources. I found that -fpermissive seems to change this to a warning instead of error, but haven't found yet how to enable it from code (using pragmas for example).
UPD: Well, I found that
#pragma GCC diagnostic ignored "-fpermissive"
does the trick, anyway I accept the answer that helped me to find this out.
<: is a digraph which is equivalent to [, thus the error. Since you don't want to modify the code a workaround is to use -fpermissive command-line argument or pragma to G++ (it actually gives you a hint):
test.cpp:9:16: note: (if you use ‘-fpermissive’ G++ will accept your code)
With gcc 4.6 I get the following error:
graphs.cpp: In function ‘int main()’:
graphs.cpp:9:15: error: ‘<::’ cannot begin a template-argument list [-fpermissive]
graphs.cpp:9:15: note: ‘<:’ is an alternate spelling for ‘[’. Insert whitespace between ‘<’ and ‘::’
graphs.cpp:9:15: note: (if you use ‘-fpermissive’ G++ will accept your code)
So, -fpermissive is the way to go. [EDIT: I see now that you added that you already found this]
Else, since you mentioned that the sources are auto-generated, you could add a post processing step. For example using sed
sed -i 's,<::,< ::,g' filename.cpp
or something similar in e.g. python. But only if you are sure you never use <:: for something else.