After declaring a __m256 fail to access its members - c++

When i tried to compile with icpc it shows "expression must have class type." Got confused about this. Please help.
int main()
{
__m256d temp;
temp.m256d_f64[0] = 1;
return 0;
}

I can reproduce this problem on my end. In the immintrin.h shipped with Intel Compiler, we have the following definition for __m256d:
typedef struct _MMINTRIN_TYPE(32) __m256d {
double m256d_f64[4];
} __m256d;
In the above definition, the struct name and alias are same which is confusing the current compiler. Intel Compiler doesn't seem to recognize the typedef name as a class which can proved with a smaller testcase:
$ cat test1.cc
typedef struct __m256d {
double m256d_f64[4];
} m256d;
int main()
{
__m256d temp;
temp.m256d_f64[0] = 1;
return 0;
}
$ icpc test1.cc –c
When I change the typedef and instantiate temp as shown below (use the typedefed name instead of struct name), ICC fails but GCC works:
$ cat test1.cc
typedef struct m256d {
double m256d_f64[4];
} __m256d;
int main()
{
__m256d temp;
temp.m256d_f64[0] = 1;
return 0;
}
$ icpc test1.cc -c
test1.cc(8): error: expression must have class type
temp.m256d_f64[0] = 1;
^
compilation aborted for test1.cc (code 2)
$ g++ test1.cc -c
I have reported this issue to compiler engineering team at Intel.

Related

cannot bind packed field 'st.ST::a' to 'int&'

using different version of gcc, compile the following code
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
there is an error:
main.cpp:21:20: error: cannot bind packed field 'st.ST::a' to 'int&'
int & ref = st.a;
But
g++ (GCC) 4.4.6 20110731 (Red Hat 4.4.6-4)
It runs all right.
If I add 'const' before the reference, and modify test function,(del t=10),like this.
It runs all right again.
const int & ref = st.a
***
int test(const int & t)
{
return 0;
}
Why?Why?Why?
#include <iostream>
using namespace std;
typedef struct
{
int a;
short b;
}__attribute__((packed)) ST;
int test(int & t)
{
t = 10;
return 0;
}
int main()
{
int a = 1;
ST st;
int & ref = st.a;
test(ref);
cout << ref << endl;
}
I have read
Passing reference of packed struct member to template. gcc bug?
and
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
But they didn't say why it runs OK using g++ 4.4.6,but had an error using 4.8.5.
they didn't say why the 'const' can make the code goes right.
This is not a new feature, why gcc has two different results?

Symbol not found in debugger only, when having templated template argument

Given the following code as test.cpp,
Building using clang++ -c test.cpp -o test.o -g; clang++ test.o -g -all_load, setting breakpoint at return a.getValue(); and attempting to p a.getValue() from lldb:
Running llvm 3.8.0 on unix - works perfectly
Running xcode or llvm 8.1.0 on OSX - I get the following error:
error: Couldn't lookup symbols:
__ZNK4Test7MyClassILi2ELi3EE8getValueEv
Two interesting facts:
If I remove the last template argument - all works well
If I build directly without going through the .o file (clang++ test.cpp) = all goes well
Anyone has a clue what is going on, and how can it be fixed?
namespace Test{
template<class T>
class BLA{
public:
T getBlaValue() const{return 3;}
};
template <int N1, int N2, template<class T>class Impl = BLA>
class MyClass {
private:
public:
__attribute__((used))
int getValue() const
{
return 3;
}
};
}
int main()
{
Test::MyClass<2, 3> a;
return a.getValue();
}

Clang static parameter to std::fill causing linker to fail

Using Clang++ (v3.8.0), the following code fails to link due to sSomeValue being an undefined reference.
#include <iostream>
struct MyClass
{
static constexpr int sSomeSize = 3;
static constexpr int sSomeValue = 10;
};
int foo()
{
int someArray[MyClass::sSomeSize] = {};
std::fill(std::begin(someArray), std::end(someArray), MyClass::sSomeValue);
return someArray[0];
}
int main()
{
std::cout << foo() << std::endl;
}
More precisely:
clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
/tmp/main-c8de0c.o: In function `foo()':
main.cpp:(.text+0x2): undefined reference to `MyClass::sSomeValue'
/tmp/main-c8de0c.o: In function `main':
main.cpp:(.text+0x16): undefined reference to `MyClass::sSomeValue'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However, changing the definition of foo to
int foo()
{
int someArray[MyClass::sSomeSize] = {MyClass::sSomeValue, MyClass::sSomeValue, MyClass::sSomeValue};
return someArray[0];
}
does not exhibit the same linker error, even though sSomeValue is still being used.
What is going on here? Is the compiler doing some optimization around the std::fill call that I may not be aware of?
Note that g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out compiles, links, and outputs 10 as expected with v6.3.0.
The error is nothing to do with std::fill.
If you refer below documentation, it says: Reference variables can be declared constexpr (their initializers have to be reference constant expressions):
http://en.cppreference.com/w/cpp/language/constexpr
Slight modification of your code works fine. Just make the struct variables "const &" as said above.
#include <iostream>
struct MyClass
{
static constexpr int const& sSomeSize = 3;
static constexpr int const& sSomeValue = 10;
};
int foo()
{
int someArray[MyClass::sSomeSize] = {};
std::fill(std::begin(someArray), std::end(someArray), MyClass::sSomeValue);
return someArray[0];
}
int main()
{
std::cout << foo() << std::endl;
}
Also refer here for well explained article about constexpr and static
"Does static constexpr variable make sense?
Specially the last para in ticked answer.

c++11 and gcc: internal compiler error: in convert_move

I have the following code:
typedef int __v8si __attribute__ ((__vector_size__ (32)));
class T
{
public:
__v8si v;
__attribute__((target("avx2")))
T(int p ):v(__extension__ __v8si{p,p,p,p,p,p,p,p}){}
__attribute__((target("avx2")))
T(__v8si p):v(p){}
__attribute__((target("avx2")))
T operator * ( T b ) const
{
return __builtin_ia32_pmulld256( v , b.v ) ;
}
};
void h(int *);
__attribute__((target("default")))
void h(int *)
{
}
__attribute__((target("avx2")))
void h(int *)
{
const T a(1);
const T b(2);
const T c (a * b);
}
int main()
{
return 0;
}
If I try to compile it,
I have the following error:
$ gcc test.cpp -std=c++11
test.cpp: In member function 'T T::operator*(T) const':
test.cpp:17:48: internal compiler error: in convert_move, at expr.c:315
return __builtin_ia32_pmulld256( v , b.v ) ;
^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
I have tried to compile it with various gcc versions:
4.9.2, 5.3 and several other versions.
Have you any ideas why it happens, and how could I solve the problem?
gcc test.cpp -std=c++11 -mavx2 works.
gcc test.cpp -std=c++11 -O1 works.
but I want to compile the code with -O0
Update 1. I've filed a bug report. The report is available here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77952

Enumerations within a struct - C vs C++

I'm trying to use Enums within a struct, this compiles and works fine with gcc.
But the same code when compiled with g++ throws an error.
#include<stdio.h>
#include<stdlib.h>
struct foo
{
enum {MODE1, MODE2, MODE3} mode;
enum {TYPE1, TYPE2} type;
};
void bar(struct foo* bar)
{
bar->mode = MODE1;
}
int main()
{
struct foo* foo = (struct foo*) malloc(sizeof(struct foo));
bar(foo);
printf("mode=%d\n",foo->mode);
}
Output obtained with gcc:
$ gcc foo.c
$ ./a.out
mode=0
Output obtained with g++:
$ g++ foo.c
foo.c: In function ‘void bar(foo*)’:
foo.c:11: error: ‘MODE1’ was not declared in this scope
MODE1 is in the scope of foo, so you need
bar->mode = foo::MODE1;
Note that if you want to access the enum types without a scope, you would need to declare them so. For example:
typedef enum {MODE1, MODE2, MODE3} MODE;
typedef enum {TYPE1, TYPE2} TYPE;
struct foo
{
MODE mode;
TYPE type;
};