strict-aliasing

Is this use of the Effective Type rule strictly conforming?

夙愿已清 提交于 2020-01-13 19:12:22
问题 The Effective Type rule in C99 and C11 provides that storage with no declared type may be written with any type and, that storing a value of a non-character type will set the Effective Type of the storage accordingly. Setting aside the fact that INT_MAX might be less than 123456789, would the following code's use of the Effective Type rule be strictly conforming? #include <stdlib.h> #include <stdio.h> /* Performs some calculations using using int, then float, then int. If both results are

Does casting a pointer back and forth from size_t or uintptr_t break strict aliasing?

喜你入骨 提交于 2020-01-13 11:32:26
问题 I'm proposing a change to a library whose public API currently looks like this: typedef size_t enh; /* handle */ int en_open(enh *handle) { struct internal *e = malloc(...); *handle = (enh)e; return 0; } int en_start(enh handle) { struct internal *e = (struct internal*)handle; return do_something(e); } Does this usage, casting back and forth to size_t break strict aliasing? For the record, I'm proposing a typical opaque forward declaration of struct internal in the public API, as shown on

How to create an uint8_t array that does not undermine strict aliasing?

↘锁芯ラ 提交于 2020-01-13 08:46:58
问题 I recently asked this question: Using this pointer causes strange deoptimization in hot loop The problem was that I was writing to an array of type uint8_t and the compiler treated it as if it could alias with the this pointer of the method (of type struct T* ), because void* and char* (= uint8_t* ) can always alias any other pointer in C++. This behaviour caused a missed optimization opportunity. I want to avoid this, of course. So the question is: Can I declare an uint8_t array that

Is placement new legally required for putting an int into a char array?

本秂侑毒 提交于 2020-01-11 15:28:29
问题 There seems to be some agreement that you can't willy nilly point (an int*) into a char array because of the C++ aliasing rules. From this other question -- Generic char[] based storage and avoiding strict-aliasing related UB -- it seems that it is allowed to (re-)use storage through placement new. alignas(int) char buf[sizeof(int)]; void f() { // turn the memory into an int: (??) from the POV of the abstract machine! ::new (buf) int; // is this strictly required? (aside: it's obviously a no

Using pointer conversions to store/cast values: Am I breaking the strict aliasing rule?

时间秒杀一切 提交于 2020-01-09 11:42:28
问题 The question relates to this post. Some authoritative users stated that the following code breaks strict aliasing rules. #include <boost/static_assert.hpp> template <typename T> struct MyType { private: T data; public: template <typename U> operator U () { BOOST_STATIC_ASSERT_MSG(sizeof(U) == sizeof(T),"Trying to convert to data type of different size"); return *((U*) &data); } template <typename U> NeonVectorType<T>& operator =(const U& in) { BOOST_STATIC_ASSERT_MSG(sizeof(U) == sizeof(T),

When is char* safe for strict pointer aliasing?

天涯浪子 提交于 2020-01-09 07:13:26
问题 I've been trying to understand the strict aliasing rules as they apply to the char pointer. Here this is stated: It is always presumed that a char* may refer to an alias of any object. Ok so in the context of socket code, I can do this: struct SocketMsg { int a; int b; }; int main(int argc, char** argv) { // Some code... SocketMsg msgToSend; msgToSend.a = 0; msgToSend.b = 1; send(socket, (char*)(&msgToSend), sizeof(msgToSend); }; But then there's this statement The converse is not true.

Does encapsulated char array used as object breaks strict aliasing rule

风格不统一 提交于 2020-01-04 03:03:21
问题 Do the following class break the strict aliasing rule: template<typename T> class store { char m_data[sizeof(T)]; bool m_init; public: store() : m_init(false) {} store(const T &t) : init(true) { new(m_data) T(t); } ~store() { if(m_init) { get()->~T(); } } store &operator=(const store &s) { if(m_init) { get()->~T(); } if(s.m_init) { new(m_data) T(*s.get()); } m_init = s.m_init; } T *get() { if (m_init) { return reinterpret_cast<T *>(m_data); } else { return NULL; } } } My reading of a standard

How to avoid strict aliasing errors when using aligned_storage

心不动则不痛 提交于 2020-01-03 12:31:53
问题 I'm using std::aligned_storage as the backing storage for a variant template. The problem is, once I enable -O2 on gcc I start getting warnings of 'dereferencing type-punned pointer will break strict aliasing`. The real template is much more complex (type checked at runtime), but a minimal example to generate the warning is: struct foo { std::aligned_storage<1024> data; // ... set() uses placement new, stores type information etc ... template <class T> T& get() { return reinterpret_cast<T&>

Strict-aliasing and pointer to union fields

为君一笑 提交于 2020-01-02 06:21:08
问题 I've got a question about strict-aliasing rules, unions and standard. Assume we have the following code: #include <stdio.h> union { int f1; short f2; } u = {0x1}; int * a = &u.f1; short * b = &u.f2; int main() { u.f1 = 1; *a += 1; u.f2 = 2; *b *= 2; printf( "%d %hd\n", *a, *b); return 0; } Now let's look how it works: $ gcc-5.1.0-x86_64 t.c -O3 -Wall && ./a.out 2 4 $ gcc-5.1.0-x86_64 t.c -O3 -Wall -fno-strict-aliasing && ./a.out 4 4 We can see that strict-aliasing breaks dependencies.

Does casting a char array to another type violate strict-aliasing rules?

╄→尐↘猪︶ㄣ 提交于 2020-01-01 08:27:08
问题 Consider these two functions: int f1() { alignas(int) char buf[sizeof(int)] = {}; return *reinterpret_cast<int*>(buf); } int f2() { alignas(int) char buf[sizeof(int)] = {}; char* ptr = buf; return *reinterpret_cast<int*>(ptr); } GCC warns that the first violates strict-aliasing rules. But the second is OK. Clang accepts both without complaint. Is the warning legitimate? 回答1: The warning is legitimate. f2 is not OK (it is undefined behaviour), it just doesn't provoke the warning. I suspect the