CLion on Windows has problem with intrinsics defined as a macro - c++

When using Intel compiler, CLion complains that _mm_extract_epi64 may be undeclared or unknown (still compilation is successful). On the other hand CLion doesn't complain on some other intrinsics functions such as _mm_set_epi64x.
The difference is that the former is defined as a macro.
#define _mm_extract_epi64(X, N) \
((long long)__builtin_ia32_vec_ext_v2di((__v2di)(__m128i)(X), (int)(N)))
while the latter is defined as an inline function
static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_set_epi64x(long long __q1,
long long __q0) {
return __extension__(__m128i)(__v2di){__q0, __q1};
}
CLion doesn't think that __builtin_ia32_vec_ext_v2di is a valid builtin function.
Same error occurs for MinGW gcc because of the same reason. Only MSVC doesn't complain because _mm_extract_epi64 is defined as extern.
Is there any fix?

Related

Compilation error C2048 while compiling in visual studio 2019 MSVC, but works fine with clang++?

I tried to compile the following sample code with clang compiler and it works fine.
Compiler Details: Apple clang version 12.0.0 (clang-1200.0.32.28)
Target: x86_64-apple-darwin20.1.0
#include <iostream>
#include <stdio.h>
int __cdecl printf(const char* format, ...)
{
std::cout<<"My printf function"<<std::endl;
return 0;
}
int main()
{
printf("Standard printf function\n");
return 0;
}
However, when I tried to compile it in visual studio 2019, it gives a compilation error.
error C2084: function 'int printf(const char *const ,...)' already has a body
What is the reason for compilation failure with MSVC?
How can I make it work, what am I missing?
My goal is to implement my version of printf() function, but wants to use other standard function available in stdio.h. How can I achieve that with MSVC?
From your code you are intentionally trying to use your own version of the printf function.
The error C2084 is expected. You are redefining something already defined. It's dangerous, and you be aware of the risks you are taking. It's a piece of a whole library and any UB (undefined Behaviour) may arise. I won't play with that. From my perspective it's g++ that is not reporting an error, but it may be that the g++/libc prototype of printf is slightly different from the one you wrote, or even, the function printf is declared in the header but not defined in there.
If you really want go down that way I strongly suggest you to define your printf in another source file and hide the libc implementation at linking time. That should be allowed (Warning and errors may arise, but every linker has an override for that).

two or more data types in declaration specifiers for typedef float _Float32;

I'm porting a pretty old C (and a bit of C++) code basis from KEIL OS to Linux 32 bit.
When compiling with gcc/g++ 6.3 to 6.5 it works ok, when trying to do the same with gcc > 7.0 (tested with 7.3 and 8.2 on ubuntu 18.04) I get compilation errors:
/usr/include/bits/floatn-common.h:207:15: error: two or more data types in declaration specifiers
typedef float _Float32;
^~~~~~~~
/usr/include/bits/floatn-common.h:244:16: error: two or more data types in declaration specifiers
typedef double _Float64;
^~~~~~~~
/usr/include/bits/floatn-common.h:261:16: error: two or more data types in declaration specifiers
typedef double _Float32x;
^~~~~~~~~
/usr/include/bits/floatn-common.h:278:21: error: two or more data types in declaration specifiers
typedef long double _Float64x;
The compiler header (/usr/include/bits/floatn-common.h:261:16) file contains the following part:
# if __HAVE_FLOAT32
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef float _Float32;
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf32() (__builtin_huge_valf ())
# define __builtin_inff32() (__builtin_inff ())
# define __builtin_nanf32(x) (__builtin_nanf (x))
# define __builtin_nansf32(x) (__builtin_nansf (x))
# endif
# endif
Which tells me that this is only related to gcc > 7.0
most of the issues related to this error are missing ";" in structs or doing something like
void int myFunction(void){}
though I think this is not the case here because it appears in different compilation units and it works with previous versions of gcc/g++
using glibc version 2.27
My question: is there a way to disable this new compiler feature or eventually a hint from the community where to start searching
Found the issue:
Somewhere in the source code there was a
#undef __GNUC__
Which was produced by a broken code generation tool...
By doing this, all inclusions of math.h or wchar.h were broken...

Wrong 32-bit calling convention for InterlockedExchange for Clang++, but MSVC is fine

I am using clang power tools to compile a project which is usually compiled using visual studio.
In boost's lwm_win32.hpp header (yes we are using an old version of boost and currently cannot update) I get an error reading.
function declared stdcall here was previously declared without calling convention
the line in question is:
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
I don't get any errors or warnings for this line when compiling with visual studio. Interestingly I don't get any even if I manually change the calling convention from __stdcall to __cdecl.
Clang tells me which previous declaration it has seen. By manually inspecting this location I would say clang is right. After deciphering all preprocessor defines I would also say __cdecl is what should be seen by visual studio. However, neither the official documentation for InterlockedExchange, nor the official documentation for the intrinsic do mention a specific calling convention.
So basically I am unsure what the root of the problem is. Visual studio accepting any calling convention in the declaration? Clang not seeing the correct declaration due to some preprocessor macros set to the wrong value? Boost declaring the wrong calling convention? I must admit I am confused.
Visual Studio version is 2015 Update 3.
Clang++ version is 6.0.0 called with parameter -fms-compatibility-version=19.
EDIT
As suggested in the comments I had a look at the preprocessor output of MSVC and Clang. They looked rather identical to me. For both the line from boost expands to
extern "C" __declspec(dllimport) long __stdcall _InterlockedExchange(long volatile *, long);
Both have
#pragma intrinsic(_InterlockedExchange)
and the declarations
long __cdecl _InterlockedExchange(long volatile * _Target, long _Value);
LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);
as well as several inline implementations for different overloads.
In both compilers I target 32-bit (-m32 for clang).
Do the clang power tools offer you things that you really don't want to live without?
If not (and I imagine that is a big if) then you might consider experimenting with VS 2017's support for clang. I have no experience of it personally and it's all still a bit new but what I do know is that MS are putting a lot of work in and it may well pay off in the long run.
As it is, I think you might be out on a bit of a limb. And whatever should and should not be in the header files, I would say that what MS say goes, wouldn't you?
Why are you stuck with that old version of boost? That might be a blocking issue here.

Clang generates errors when I try to use AVX features

I'm on Windows 10, with Clang version 5 (recently installed). When I compile the following
#define __AVX__
#define __AVX2__
#include <immintrin.h>
int main(void) {
__m256i a, b, result;
result = _mm256_add_epi64(a, b);
return 0;
}
I get the following error:
error: always_inline function '_mm256_add_epi64' requires target
feature 'avx2', but would be inlined into function 'main' that is
compiled without support for 'avx2'
result = _mm256_add_epi64(a, b);
^
MSVC compiles it just fine. What compiler option do I need to use in order to get Clang to compile this? Or is there something else going on?
If you are native compiling (host and target being the same machine so, not cross-compilation), then consider passing -march=native to clang
See also the user manual of the Clang compiler.
Notice that the Clang compiler is open source. You are allowed to download its source code and improve it.

How to get Coverity static analysis compatible with C++0x standard?

I am using a Wind River Compiler 4 (gcc (C) and g++ (C++)) and it compiles all my projects without any problems. Now I have to use Coverity Static Analysis to check my code. I have configured the specific compilers. For the C-Code (gcc) there are no problems and I can run the analysis, but for the C++-Code (g++) I got a lot of errors:
.../c++config.h", line 214: error #40:
expected an identifier
inline namespace __gnu_cxx_ldbl128 { }
^
.../c++config.h", line 214: error #326:
inline specifier allowed on function declarations only
inline namespace __gnu_cxx_ldbl128 { }
^
.../c++config.h", line 214: error #65:
expected a ";"
inline namespace __gnu_cxx_ldbl128 { }
^
.../include/string.h", line 76: error #312:
cannot overload functions distinguished by return type alone
extern __const void *memchr (__const void *__s, int __c, size_t __n)
^
.../include/string.h", line 116: error #312:
cannot overload functions distinguished by return type alone
extern "C++" __const void *memchr (__const void *__s, int __c, size_t __n)
^
It seem to be some C++11 specific features like the inline namespace but the code doesn't use these features. The errors above are produced with a HelloWorld-Code:
#include "stdio.h"
#include "util.h"
#include <string>
#include "string.h"
using namespace std;
int main()
{
printf("Hello World, C++ version: %d.%d.%d\r\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
return 0;
}
I have tried to set the c++ standard with the g++ option
-std=c++98
but the result doesn't changed.
The Test-Code is in a big build hierarchy but the steps for Coverity are like this:
target and env set (Wind River 4 Linux)
make clean
cov-configure with compiler dir and type
cov-build with the correct "make all" command that works alone
cov-analyze
if (no_error) cov-commit-defects
I have also configured Coverity to replace all "inline namespace" with "namespace" during the cov-build (--ppp-translator replace/inline namespace/namespace). The inline errors disappeared but it produces more of this overload errors and no succecfully build. Also tried to remove the "C++" the same way but didn't work there are always more errors.
Does anybody have an idea what is the problem here? And how can I get the Coverity build without errors? Maybe I can configure Coverity to ignore c++ standard headers but I don't now how?
Your library implementation is using C++11. Presumably there are #ifdefs that remove all the C++11 stuff when you do call g++ with -std=c++98 but it seems that however Coverity is integrated with g++, it's not defining the same things that are necessary to avoid the C++11 features.
You should figure out what the macros that gcc uses around that C++11 code are and then make sure that Coverity is defining them appropriately as well when it analyzes your project.
Workaround by Coverity Support:
The inline namespace is a known bug in Coverity. To bypass it, configure Coverity with the following additional options (in the config file):
<begin_command_line_config></begin_command_line_config>
<add-arg>--ppp_translator</add_arg>
<add_arg>replace/inline namespace ([_a-zA-Z0-9]*)\s+\{\s*\}/namespace $1 { } using namespace $1;</add_arg>
</options>
After that we got some other errors but they seem to belong all to string definitions. Now add a Coverity define at the beginning of coverity-compiler-compat.h (also in the config dir):
#define __COVERITY_NO_STRING_NODEFS__
After these changes the cov-build runs without errors and the analysis can be started.
This error says it quite clearly:
inline specifier allowed on function declarations only
Is there a reason the namespace is inline? While I don't have the specification available, so I can't tell you if it's allowed or not. (That the compiler allows it may be a bug in GCC.)
Try to remove that inline and Coverity will hopefully by happy.
It seems that Coverity hasn't been updated with the some C++11 features, like inline namespaces.