开发者

C++ Void non-pointer

I was wondering, why can't there be a void data type that is not a pointer?

Surely you could get past the whole determined size thing by having

void4
void8
void32

And then only being allowed to 'cast' a void data type to another class if its size is equal or under to the classes size.

Is there something that I开发者_StackOverflow社区'm missing, or does the C++ committee just consider it bad practise?

EDIT:

I haven't explained myself very well, so I'll give an example of its use:

 main()
{
    /* 

     Lets make a list of unknown elements

     std::string is 8 bytes, and float is 4
     bytes, so we'll reserve 8 byte sequences

     */

    vector<void8> elements;

    elements.push_back((void8) string("First string element"));

    elements.push_back((void8) float(5.76) );

    elements.push_back((void8) string("Third string element"));

    // Ect.

    cout << (string) elements[0];
    cout << (float) elements[1];
    cout << (string) elements[2];
    cout << (float) elements[2]; // Garbage


    void1 data;

    data = (void1) bool(1);
    data = (void1) unsigned int(80094); // Error, not enough size
}

Its named void because you don't know what type it is currently storing, similar to the void pointer.


It's called a boost::variant or boost::any. It's the size of the maximum allowed data type + sizeof(pointer) and is totally type safe.


In a strongly typed language, all data has a type, so there is no concept of "void" as a datatype. In C and C++, it's meanings are either "no data" (as a return value), or "data whose type you don't know" (as a pointer target).

You are proposing an in-between state of "data whose type you don't know but whose size you do", presumably as an opaque version of a type you pass by value. Besides being rather a dangerous thing to do (since you have to manually update all the code using the opaque type when you change the size of the real type), this can already be done without adding weird extensions to the language, for example:

struct void8 { char bytes[8]; };

This could be used in conjunction with reinterpret_cast to pass POD types around as opaque lumps, in much the way you suggest. Using it with non-POD types is even more likely to invoke undefined behaviour than using void* to refer to non-POD types.

It would be safer and more idiomatic to handle opaque types as pointers or references to named types that have been declared but not defined, or something like boost::any if you want value semantics. There's rarely a need to use "void" as a placeholder type in C++.


What is void? It is nothing, emptyness. Void32, lol! void used to designate function that returns nothing. In other languages there is keyword 'procedure' or 'sub'. Pointer to void is pointer to unknown (second usage of void). That's two purposes void serves.

Update: I think, author wants to designate unknown type with known size. void32* is pointer to some entity with sizeof 32 bits, void8* is pointer to 8-bit entities and so on. But it's easily emulated with int32*, char* without language extension.


What you're looking for already exists. It is called char. An array of char can be used to store unknown objects into, because a char is basically C++'s name for a byte. So to store unknown or variable types of objects into a single array, you use an array of bytes, not an array of nothing, which void would be.

The point in a void pointer is that we don't know what it points to. We don't know the size of the object it points to either. So a void4 doesn't make much sense. It's no longer "void" if we know the object's size. The only thing we can do with an unknown object is to point to it. We can't store it anywhere because we don't know if it is a POD object, and we don't know how big it is, or its alignment requirements. So we certainly not store it into an array. All we can do is create a pointer to it, and we already have void pointers for that.

And of course, a fun little question:

What is the type T here?

void foo(void* p) {
   T q = *p;
}

void4? void32? Or just void? How big should the object be? What do we know about it? Is it a POD type?


What would be the meaning of a "void" data type? I don't think there is a valid one, so that's probably why it doesn't exist.


Having a void datatype would unnecessarily complicate things. and Moreover what would the datatype be doing if it is called void.

I guess you are referring to a datatype that may funciton like a void one but you may want to change the name and not call it void.


void* is not a pointer which is void, as in invalid. It's a pointer to a void, as in there's nothing there.

Type type void itself is defined by the lack of a value. There are no bits in its representation. It cannot form objects.

What you are describing can be casted to and from. Therefore it contains information. Therefore it is not an empty void.

What you are describing is simply an int where the numerical value is ignored. But the suggested uses are poor practice.


void is an "uninhabited" type, meaning there are no possible values of type void. Since there are no possible values, it takes no space to store a void. Therefore, sized void values would be meaningless.

Stepping back a moment: C and C++ fairly consistently recognize void as meaning "nothing". You can have a pointer to nothing, and use it to carry the value of a pointer to something around, but you cannot dereference it - void has no value that you can do anything with.

Note as well that the void-is-nothing carries through to the void pointer case: while some compilers such as GNU allow you to do pointer arithmetic on void* values as if they were char*, the standards prohibit pointer arithmetic on void* because, since void is nothing, it has no meaningful size.

So, I think the answer is: it would be meaningless. void is nothing, and you can't store nothing in a value.


I'm going to assume you know a little more about the things that you will be storing than just their size, otherwise I don't believe there is much point in storing those items.

I think that you might want to take a look at unions. A union reserves enough space to hold the largest member of the union and then depending on how you reference the union, selects the "appropriate" amount of space and gives it to you as the type you request.

That said, much like casting an array of characters to whatever type you are actually looking for, you should think hard before you use this sort of feature.


If there were a void datatype I think it should represent nothing and just swallow anything stored into it.

you can say

(void)func1();

so why not

void x;
x = func1();

or

void func2() {
   void x;
   ...
   return x;
}

and as function arguments

int func3(int x, void y, char z);

void x = func3(1,2);
x = func3(1,x,2);

Using void in an expression is an error

I can see uses for this in some template coding.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜