I am using a C++ implementation of an algorithm which makes odd usage of special pointer values, and I would like to known how safe and portable is this.
First, there is some structure containing a pointer field. It initializes an array of such structures by zeroing the array with memset(). Later on, the code relies on the pointer fields initialized that way to compare equal to NULL; wouldn't that fail on a machine whose internal representation of the NULL pointer is not all-bits-zero?
Subsequently, the code sets some pointers to, and laters compares some pointers being equal to, specific pointer values, namely ((type*) 1) and ((type*) 2). Clearly, these pointers are meant to be some flags, not supposed to be dereferenced. But can I be sure that some genuine valid pointer would not compare equal to one of these? Is there any better (safe, portable) way to do that (i.e. use specific pointer values that can be taken by pointer variables only through explicit assignment, in order to flag specific situations)?
Any comment is welcome.
To sum up the comments I received, both issues raised in the question are indeed expected to work on "usual" setup, but comes with no guarantee.
Now if I want absolute guarantees, it seems my best option is, for the NULL pointers, set them either manually or with a proper constructor, and for the special pointer values, to create manually sentinel pointer values.
For the latter, in a C++ class I guess the most elegant solution is to use static members
class The_class
{
static const type reserved;
static const type* const sentinel;
};
provided that they can be initialized somewhere:
const type The_class::reserved = foo; // 'foo' is a constant expression of type 'type'
const type* const The_class::sentinel = &The_class::reserved;
If type is templated, either the above initialization must be instantiated for each type intended, or one must resort to non-static (less elegant but still usefull) "reserved" and "sentinel" members.
template <typename type>
class The_class
{
type reserved; // cannot be static anymore, nor const for complicated 'type' without adapted constructor
const type* const sentinel;
public:
The_class() : sentinel(&reserved);
};
Related
I want to use constexpr instead of #defines wherever possible, for type safety and namespace features.
Unfortunately, I get this error: 'reinterpret_cast<SPI_TypeDef*>(1073756160)' is not a constant expression when trying.
#include <stm32f0xx.h> // #defines SPI2 as pointer to a struct of volatile unsigned ints
constexpr auto myPort = SPI2;
I'm not looking for an explanation of why reinterperet_cast cannot be used in a constexpr.
What is the modern C++ way to have a constexpr pointer to some memory mapped hardware?
One reason for this is to use these constexpr values in templated code.
constexpr code wasn't invented so that you could avoid using #defines; it's there so that you can do certain things with expressions that you couldn't otherwise. You can pass constexpr pointers or integers as template parameters, for example, since they are constant expressions.
Basically, the primary purpose of any constexpr variable or function is to be able to be used within compile-time programming. So to declare a variable to be constexpr is to say "this is a compile-time constant and it's reasonable to use it at compile-time."
A pointer whose value is an arbitrary address cannot be used at compile-time. So marking such a pointer as a compile-time value is a contradiction. So you're not allowed to do it. constexpr pointers are required to be real pointers, which are either null pointers or point to actual objects. Not to arbitrary addresses.
It's not possible. Even std::bit_cast, which can in certain cases emulate reinterpret_cast at compile-time, loses its constexpr-ness when one of the involved types is a pointer.
Like other answers already state, it is not possible for arbitrary pointers.
If it is "for type safety and namespace features [...] to some memory mapped hardware" you are asking for, why you don't just use
// assumed preconditions, since not provided in question
typedef struct {
volatile unsigned int a;
volatile unsigned int b;
} SPI_TypeDef;
SPI_TypeDef* SPI2 = (SPI_TypeDef*)0x12345678;
// actual answer
SPI_TypeDef* const myPort = SPI2;
This way your pointer myPort to some data of type struct SPI_TypeDef is const, but not the pointed-to struct.
const keyword is generally "left-assigning".
Consider
Foo data[]={{...},{...},{...}};
Foo data_end={...};
If the end marker is defined right after the array, is it guaranteed that
&data[3]==&data_end
I do not want having to count the number of elements in data manually.
It happens to look OK in gdb without any optimization option, but before using it I need to know that the compiler cannot move data_end. If it can, how can I do instead.
Not only what you request is not guaranteed, but moreover, a C++03-compliant implementation must ensure that &data[3] != &data_end:
5.10 Equality operators[expr.eq]
1 … Two pointers of the same type compare equal if and only if they are both null, both point to the same object or function, or both point one past the end of the same array.
In C++11, it is a little more complicated:
Two pointers of the same type compare equal if and only if they are both null, both point to the same function, or both represent the same address (3.9.2).
3.9.2 notes:
… If an object of type T is located at an address A, a pointer of type cv T* whose value is the address A is said to point to that object, regardless of how the value was obtained. [Note: for instance, the address one past the end of an array (5.7) would be considered to point to an unrelated object of the array’s element type that might be located at that address. … —end note]
Thus, the new standard allows that a complying implementation might yield true in your comparison; still, there are no guarantees.
If you need to count the number of elements of an array, use the following stock macro:
#define countof(ARR) (sizeof (ARR) / sizeof *(ARR))
Or if you don't like macros, use the following function:
template<class T, std::size_t N>
constexpr std::size_t countof(T (&)[N])
{
return N;
}
The latter option, however, needs that your compiler support the constexpr keyword to be full functional equivalent of the former.
No. It is not a reliable assumption that the compiler places the variables in any order or any alignment. There can be gaps between the variables for alignment and I've already seen compilers that order variables alphabetically.
If you want to know the pointer to the element that is not in the array you need to know the number of array elements.
#define _dimof(a) (sizeof(a)/sizeof(a[0]))
Foo data[] = ... ;
// The type of the variable has been changed.
Foo* data_end = &data[_dimof(data)];
You may remove this paragraph since it has been added in order to fix a syntax error in the code.
No it is not reliable, in C++11, just do
for (/* const */ Foo& foo : data) {
// stuff with foo.
}
I'm trying to implement a C++ class with a value field that can point to anything (a bit like in boost::any). Currently I do the following:
class MyClass {
void* value;
template<typename T>
Myclass(const &T v) {
value = (void*)(new T(v));
}
};
The problem is now to implement a getValue() operation that creates a copy of the inner value with the right type:
template<typename T>
T getValue() {
return *value;
}
Here it cannot work because I'm trying to unreference a void* pointer. I was wondering which cast (static_cast? dynamic_cast? other...) I should use such that *value is properly converted into a T object and an exception is thrown if value was not originally of this type?
Thanks
You cannot dereference a void*, it simply makes no sense. Why not make the class itself generic? Then you can have:
template<typename T>
class MyClass {
T* value;
MyClass(const T& v) {
value = new T(v);
}
T getValue() {
return *value;
}
};
Make sure to create a destructor which deallocates value and also to follow The Rule of Three. You could also make a version of getValue that returns a const T& (const reference to T) to avoid the copy if one is not required.
which cast (static_cast? dynamic_cast? other...) I should use such that *value is properly converted into a T object
If you must do this conversion, then you should use static_cast, which in general is designed to (among other things) reverse any standard conversion. There's a standard conversion from any object pointer type to void*, and your getter reverses it, so use the cast designed for that:
return *static_cast<T*>(value);
You should also either remove the C-style cast from your constructor, or replace that with a static_cast too.
A reinterpret_cast would also work, but is "overkill". In general you should use the cast that is as restrictive as possible while still performing the conversion you need.
and an exception is thrown if value was not originally of this type
You are out of luck there - C++ cannot in general tell what the original type of the object was, once you've cast the pointer to void*. Your code relies on the caller to call getValue with the correct type. For example, consider what happens if the original type was char -- that's just one byte in C++, there is no room set aside for any type information that would allow the compiler to check the cast in getValue.
dynamic_cast does check types in some limited circumstances, but since your template is fully generic, those limited circumstances might not apply.
If you don't like this, you could change your class to store, in addition to the object pointer, a pointer to a type_info object (resulting from a use of the typeid operator). See the standard header <typeinfo>. You could then compare the type_info object for the type T in the constructor, with the type_info object for the type T in getValue, and throw if they don't match.
As you say, your class is intended to be a bit like boost::any, and getValue is like any_cast. You could consult the source and documentation of that class to see the tricks needed to do what you want. If there were a straightforward way to do it, then boost::any would be a straightforward class!
You can't. C++ doesn't provide that sort of mechanism, at least not directly, not for void*. A void* does not have any information that the computer would need to determine what it is, and attempting to "check" if it is a valid whatever-you-cast-it-to is impossible because there aren't particular flags for that.
There are options, though. The first is to use some kind of universal base class, similar to Java's Object, and derive all of your other classes from that. dynamic_cast will now work the way you want (returning NULL if the object is not a valid object of the class you casted it to).
Another is to simply keep track of what type of object it is yourself. That means augmenting the void* with another value that tells you what you need to cast it to.
But really, neither of these things strike me as good ideas. I think there is almost-definitely some other aspect of your design that should be changed rather than using these. Using templates, as #EdS. suggests, is a very good option, for example.
In other words, may I reinterpret (not convert!) void* pointer as a pointer to some structure type (assuming that the void* pointer really holds properly converted valid structure address)
Actually I'm interesting in the following scenario:
typedef struct void_struct void_struct_t;
typedef somestruct
{
int member;
// ... other members ...
}somestruct_t;
union
{
void* pv;
void_struct_t* pvs;
somestruct_t* ps;
}u;
somestruct_t s={};
u.pv= &s;
u.ps->member=1; // (Case 1) Ok? unspecified? UB?
u.pvs=(void_struct_t*)&s;
u.ps->member=1; // (Case 2) )Ok?
What I found in the C11 standard is rather dissapointing for the Case 1:
§6.2.5
28 A pointer to void shall have the same representation and alignment requirements as a
pointer to a character type.[footnote: The same representation and alignment requirements
are meant to imply interchangeability as arguments to functions, return values from
functions, and members of unions.] Similarly, pointers to qualified or unqualified
versions of compatible types shall have the same representation and alignment
requirements. All pointers to structure types shall have the same representation and
alignment requirements as each other. All pointers to union types shall have the same
representation and alignment requirements as each other. Pointers to other types need not
have the same representation or alignment requirements.
It seems, though, that Case 2 is valid, but I'm not 100% sure...
The question is mostly C-oriented, but I'm interesting in C++ too (I'd want the code would be valid while compiling by C++ compiler). Honestly, I found even less in C++11 standard, so even Case 2 seems questionable for me... however, may be I'm missing something.
[edit]
What is the real problem behind this question?
I have a (potentially large) set of types defined as structs.
For each type I need to define a companion type:
typedef struct companion_for_sometype
{
sometype* p_object;
// there are also other members
}companion_for_sometype;
Obviously, the companion type would be a template in C++, but I need a solution for C
(more exactly, for "clean C", i.e for intersection of C89 and C++ as I want my code to be also valid C++ code).
Fortunately, it is not a problem even in C, since I can define a macro
DECLARE_COMPANION(type_name) typedef struct companion_for_##type_name
{
type_name* p_object;
// there are also other members
}companion_for_##type_name;
and just invoke it for every type that need a companion.
There is also a set of generic operations on companion types.
These operations are also defined by macros (since there are no overloads in pure C).
One of this operations, say
#define op(companion_type_object) blablabla
should assign a void* pointer to p_object field of the companion object,
i.e. should do something like this:
(companion_type_object).p_object= (type_name*) some_function_returning_pvoid(..)
But the macro doesn't know type_name (only an object of companion type is passed to the macro)
so the macro can't do the appropriate pointer cast.
The question is actually inspired by this problem.
To solve it, I decide to reinterpret target pointer in the assignment as void* and then assign to it.
It may be done by replacing the pointer in the companion declaration with a union of pointers
(the question is about this case), or one may reinterpret target pointer directly, say:
*(void**) &(companion_type_object).p_object= some_function_returning_pvoid(..)
But I can't find any solution without reinterpreting pointers (maybe I'm missing some possibilities though)
void * is a pointer that can hold any object pointer type, that includes all pointers to structure type. So you can assign any pointer to a structure type to a void *.
But void * and pointers to structure types are not guaranteed to have the same representation so your case 1 is undefined behavior.
(C11, 6.2.5p28) "[...] Pointers to other types need not have the same
representation or alignment requirements."
In C, void * automatically casts to any object type, so this will work:
(companion_type_object).p_object = some_function_returning_pvoid(..)
In C++, you need to use static_cast, but you can find out the required type using decltype :
(companion_type_object).p_object =
static_cast<decltype(*(companion_type_object).p_object) *>(
some_function_returning_pvoid(..))
In C++03 you should be able to use some compiler extension equivalent to decltype. Alternatively, you could provide a macro-generated method on companion_type_object to cast a void * to the appropriate type:
static type_name *void_p_to_object_p(void *p) { return static_cast<type_name *>(p); }
...
(companion_type_object).p_object = companion_type_object.void_p_to_object_p(
some_function_returning_pvoid(..))
If I have the following struct:
struct Foo { int a; };
Is the code bellow conforming with the C++ Standard? I mean, can't it generate an "Undefined Behavior"?
Foo foo;
int ifoo;
foo = *reinterpret_cast<Foo*>(&ifoo);
void bar(int value);
bar(*reinterpret_cast<int*>(&foo));
auto fptr = static_cast<void(*)(...)>(&bar);
fptr(foo);
9.2/20 in N3290 says
A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.
And your Foo is a standard-layout class.
So your second cast is correct.
I see no guarantee that the first one is correct (and I've used architecture where a char had weaker alignment restriction than a struct containing just a char, on such an architecture, it would be problematic). What the standard guarantee is that if you have a pointer to int which really point to the first element of a struct, you can reinterpret_cast it back to pointer to the struct.
Likewise, I see nothing which would make your third one defined if it was a reinterpret_cast (I'm pretty sure that some ABI use different convention to pass structs and basic types, so it is highly suspicious and I'd need a clear mention in the standard to accept it) and I'm quite sure that nothing allow static_cast between pointers to functions.
As long as you access only the first element of a struct, it's considered to be safe, since there's no padding before the first member of a struct. In fact, this trick is used, for example, in the Objecive-C runtime, where a generic pointer type is defined as:
typedef struct objc_object {
Class isa;
} *id;
and in runtime, real objecs (which are still bare struct pointers) have memory layouts like this:
struct {
Class isa;
int x; // random other data as instance variables
} *CustomObject;
and the runtime accesses the class of an actual object using this method.
Foo is a plain-old-data structure, which means it contains nothing but the data you explicitely store in it. In this case: an int.
Thus the memory layout for an int and Foo are the same.
You can typecast from one to the other without problems. Whether it's a clever idea to use this kind of stuff is a different question.
PS:
This usually works, but not necessarily due to different alignment restrictions. See AProgrammer's answer.