473,657 Members | 2,735 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

stupid void**

In C and in older C++ compilers, you could write code like this

void a(void** pp); // declare a function that takes a pointer to a pointer-to-void.
struct I {}; // some struct.
I *i1,**i2; // some kinds of i.

a(&i1); // this works
a(i2); // this also worked.
a(i1); // error: incorrect levels of indirection
a(&i2); // error: incorrect levels of indirection

Now, c++ compilers just don't like void* anymore. meaning we absolutely have to static cast to a void** because c++ compiler are too damn high and mighty to let a void** slip past on a mere levels of indirection check.

a((void**)&i1); // this works
a((void**)i2); // this also worked.
a((void**)i1); // oops
a((void**)&i2); // oops

Yay for c++ helping us avoid bugs.
indirection checking was useful damnit.
Nov 12 '08 #1
10 1789
Chris Becke wrote:
In C and in older C++ compilers, you could write code like this

void a(void** pp); // declare a function that takes a pointer to a pointer-to-void.
struct I {}; // some struct.
I *i1,**i2; // some kinds of i.

a(&i1); // this works
a(i2); // this also worked.
a(i1); // error: incorrect levels of indirection
a(&i2); // error: incorrect levels of indirection
No, you couldn't. Neither in C nor in C++. None of these ever "worked".
Apparently, you've been using some silly old broken compiler and a bunch
of your own hacks, and for some reason mistook that compiler's silly
quirks for C and/or C++ language features.
Now, c++ compilers just don't like void* anymore. meaning we absolutely
have to static cast to a void** because c++ compiler are too damn high
and mighty to let a void** slip past on a mere levels of
indirection check.
Huh? You seemed to be talking about 'void**'. And here you suddenly
mention 'void*', which has very little to do with 'void**'.

BTW, "static cast to void**"? The casts in question cannot be performed
by 'static_cast'. If your compiler allows it, it probably means that you
are continuing to stick with some rather silly compiler.
a((void**)&i1); // this works
a((void**)i2); // this also worked.
a((void**)i1); // oops
a((void**)&i2); // oops

Yay for c++ helping us avoid bugs.
indirection checking was useful damnit.
All these four calls are "bugs", just like the original four calls were.
The are "bugs" in a sense that that the resultant pointer cannot be
immediately used as a 'void**' pointer anyway. The compiler you are
using now looks better because it refuses to compile the useless
original code. This should have been something to make you think about
what you are doing. Instead, you decided to slap a cast on it to sweep
the error under the carpet. Well, no wonder all you get from it is a
bunch of "oops"!

--
Best regards,
Andrey Tarasevich
Nov 12 '08 #2
Chris Becke wrote:
In C and in older C++ compilers, you could write code like this

void a(void** pp); // declare a function that takes a pointer to a
pointer-to-void.
struct I {}; // some struct.
I *i1,**i2; // some kinds of i.

a(&i1); // this works
a(i2); // this also worked.
a(i1); // error: incorrect levels of indirection
a(&i2); // error: incorrect levels of indirection

Now, c++ compilers just don't like void* anymore. meaning we absolutely
have to static cast to a void** because c++ compiler are too damn high
and mighty to let a void** slip past on a mere levels of indirection
check.

a((void**)&i1); // this works
a((void**)i2); // this also worked.
a((void**)i1); // oops
a((void**)&i2); // oops

Yay for c++ helping us avoid bugs.
Yes, indeed, disallowing it eliminates bugs. If T** implicitly converted
to void**, you could do

int* p;
void** pp = &p; // error, but you're arguing that this be allowed
char c;
*pp = &c; // if allowed, would be equivalent to
// reinterpret_cas t<void*&(p) = &c
*p = 1234; // oops, p points to a char

without any casting. Also, if the standard required a compiler to allow
this, it would have to use the same representation for all pointer types,
rather than as currently where it can use fewer bits for pointers to types
with alignment requirements more strict than char's.
Nov 12 '08 #3
On Nov 12, 10:21*pm, "Chris Becke" <chris.be...@gm ail.comwrote:
In C and in older C++ compilers, you could write code like this

* void a(void** pp); // declare a function that takes a pointer to a pointer-to-void.
* struct I {}; // some struct.
* I *i1,**i2; // some kinds of i.

* a(&i1); *// this works
* a(i2); * * // this also worked.
* a(i1); * * // error: incorrect levels of indirection
* a(&i2); *// error: incorrect levels of indirection
Just backing up what Andrey said; none of these ever
worked in any standard version of C or C++. A void**
can only point to exactly a void* , not anything else.

Nov 13 '08 #4
"blargg" <bl********@gis hpuppy.comwrote in message news:bl******** *************** **@192.168.1.4. ..
Chris Becke wrote:
without any casting. Also, if the standard required a compiler to allow
this, it would have to use the same representation for all pointer types,
rather than as currently where it can use fewer bits for pointers to types
with alignment requirements more strict than char's.
C99 still allows transformation to AND from void*

void* x;
int* y;
x=y; // both are legal in C99. At least the latest versions of MSVC and GCC compile this fragment.
y=x;

That aside, I do get the problem with pointer representations .

But, it seems a bit subversive to have a universal pointer type, and then disallow it being used as a universal pointer type. In its current form in c++, void* should have just been thrown out. It saves us a typecast only when casting to, not from void*s, and c++ hasn't introduced any kind of indirection counting typecast, making void* worse than dangerous. All because some overly zelous individual decided that void** needs to be treated as a special case, definately note a pointer to a thing that is a void*.
Nov 13 '08 #5
On Nov 13, 9:18 am, "Chris Becke" <chris.be...@gm ail.comwrote:
"blargg" <blargg....@gis hpuppy.comwrote in
messagenews:bl* *************** *********@192.1 68.1.4...
Chris Becke wrote:
without any casting. Also, if the standard required a
compiler to allow this, it would have to use the same
representation for all pointer types, rather than as
currently where it can use fewer bits for pointers to types
with alignment requirements more strict than char's.
C99 still allows transformation to AND from void*
void* x;
int* y;
x=y; // both are legal in C99. At least the latest versions of MSVC and GCC compile this fragment.
y=x;
As does C++. The only difference is that C++ requires a
static_cast for the conversion from void*.
That aside, I do get the problem with pointer representations .
But, it seems a bit subversive to have a universal pointer
type, and then disallow it being used as a universal pointer
type.
The universal pointer type is void*, not void**.
In its current form in c++, void* should have just been thrown
out. It saves us a typecast only when casting to, not from
void*s,
Which is probably a mistake---it should probably require the
conversion to be explicit in both directions.
and c++ hasn't introduced any kind of indirection
counting typecast, making void* worse than dangerous.
I'm not sure that I follow you here. C++ didn't change the
meaning of void* from that of C.
All because some overly zelous individual decided that void**
needs to be treated as a special case, definately note a
pointer to a thing that is a void*.
What? void** (unlike void*) isn't a special case at all; it's a
pointer to a void*, and only to a void*. If I understand your
initial code, you wanted it to point to an int*.

And I don't know who you mean by "some overly zealous
individual". It's been that way in both C and C++ ever since
there was void.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Nov 13 '08 #6
On Nov 13, 1:15 am, Old Wolf <oldw...@inspir e.net.nzwrote:
On Nov 12, 10:21 pm, "Chris Becke" <chris.be...@gm ail.comwrote:
In C and in older C++ compilers, you could write code like this
void a(void** pp); // declare a function that takes a pointer to a pointer-to-void.
struct I {}; // some struct.
I *i1,**i2; // some kinds of i.
a(&i1); // this works
a(i2); // this also worked.
a(i1); // error: incorrect levels of indirection
a(&i2); // error: incorrect levels of indirection
Just backing up what Andrey said; none of these ever
worked in any standard version of C or C++. A void**
can only point to exactly a void* , not anything else.
You can drop the standard---they've never worked in any version
of C or C++. (Some very, very early versions of C did allow
implicit conversions between any pointer types. Even then,
however, this was documented as and "unintentio nal"
feature---that the language itself required an explicit
conversion. And of course, this was long before there was a
keyword void.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Nov 13 '08 #7
Chris Becke wrote:
>
C99 still allows transformation to AND from void*

void* x;
int* y;
x=y; // both are legal in C99. At least the latest versions of MSVC and GCC compile this fragment.
y=x;

That aside, I do get the problem with pointer representations .

But, it seems a bit subversive to have a universal pointer type, and then
disallow it being used as a universal pointer type. In its current
form in c++, void* should have just been thrown out.
This is all great, but it is about 'void*', while your original message
was about 'void**', which is a completely different thing.
It saves us a typecast only when casting to, not from void*s, and c++
hasn't introduced any kind of indirection counting typecast,
C doesn't have any "indirectio n counting typecasts" either. If you saw
something like that in the past, it probably was a fancy feature of some
specific compiler.
making void* worse than dangerous.
'void*'??? No.
All because some overly zelous individual decided that void** needs to
be treated as a special case, definately note a pointer to a thing
that is a void*.
No, you got it completely upside down. 'void**' is not treated as a
special case. The contrary is true: 'void**' is treated as a general
case. 'int**' cannot converted to 'void**' for precisely the same
reasons why, say, 'int*' cannot be converted to 'double*' (despite the
valid 'int' -'double' conversion).

--
Best regards,
Andrey Tarasevich
Nov 13 '08 #8
Chris Becke wrote:
"blargg" <bl********@gis hpuppy.comwrote in message
news:bl******** *************** **@192.168.1.4. ..
>Chris Becke wrote:
without any casting. Also, if the standard required a compiler to allow
this, it would have to use the same representation for all pointer types,
rather than as currently where it can use fewer bits for pointers to
types with alignment requirements more strict than char's.

C99 still allows transformation to AND from void*
Yes. but a pointer to void is not the same as a pointer to a pointer.
But, it seems a bit subversive to have a universal pointer type, and then
disallow it being used as a universal pointer type.
It's not. For any pointer, the standard requires that its value can be
converted to void* and back without loss. What it doesn't say is that such a
pointer can be converted into a pointer to pointer and back without loss.
It saves us a typecast only when casting to, not from void*s, and c++
hasn't introduced any kind of indirection counting typecast, making void*
worse than dangerous.
A void** isn't just a void pointer with one additional level of indirection
or something like that. It's a different pointer type.
All because some overly zelous individual decided that void** needs to be
treated as a special case, definately note a pointer to a thing that is a
void*.
There is no special case. void** is just handle the same as pointers to any
other pointer type.

Nov 13 '08 #9
On 2008-11-13 13:28:17 -0500, Rolf Magnus <ra******@t-online.desaid:
>
A void** isn't just a void pointer with one additional level of indirection
or something like that. It's a different pointer type.
And it can be implicitly converted to void*, just like any other pointer type.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Nov 13 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
3132
by: raz | last post by:
Greetings all. I apologize for what is almost certainly a stupid question, but I can't figure this out, and have no more time for head bashing... The short version: what is the appropriate include file to define the CString type in an MFC based app? The longer version:
4
1442
by: IS | last post by:
At the recommendation of several people in this newsgroup I have downloaded two or three Compilers. One is the Beta version of Microsoft's Visual C++ 2005. I have entered a complete beginner code that looks like this: #include <iostream> using namespace std: //introduces namespace std int main( void )
4
3112
by: Uchiha Jax | last post by:
Hello everyone, I am a plenty silly person who is trying to learn .NET remoting through trial and error (all articles I read are going over my head at the moment (mostly) so I thought i'd give it a go). What I want to do is this: Have a server instance of the program, this server instance will receive communication from client programs (as demonstrated in the AddMessage()
8
1396
by: StillStuckOnJava | last post by:
I'm using visual studio to create a web application, but I'm having trouble using a few classes that I've defined: public class tank { public tank() { } public float depth; public float maxMudLvl;
5
1261
by: StillStuckOnJava | last post by:
I'm having a stupid problem with V.S./C#. I've created a class and two subclasses, and I want to instantiate either of hte subclasses after users make a selection. Then I want to use that class to modify its members as users make more selections. IT'S NOT WORKING DAMN IT! The following is my asp.net behind code for the web form, and then my class code. I'm getting an error when I try to access the class instance that I previously...
3
7108
by: Catweasel | last post by:
I'm new to C++ and have been chucked in at the deep-end. I have a C++ console app that works fine. All I want to do is write to file however as soon as I include the fstream library and try to compile VS .net chucks out errors, lots of them: c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\cstdio(17) : error C2143: syntax error : missing '{' before ':' c:\Program Files\Microsoft Visual Studio .NET
0
902
by: engwar | last post by:
C# newbie here. I'm creating a page that will use a repeater control to display thumbnail images. I want to have a button next to each image so that the user can delete a particular image by clicking on the 'delete' button next to it. I'm having trouble determining how to pass the id of the image to my codebehind when the user clicks a particular delete button.
7
2252
by: badc0de4 | last post by:
Is this a stupid hack or a clever hack? Is it a "hack" at all? ==================== #include <stdio.h> /* !!HACK!! */ /* no parenthesis on the #define'd expression */ #define MY_FLOAT_CONSTANT_HACKED 15 / 4
1
15088
by: eraserwars | last post by:
I have been googeling every possible solution, but I cannot seem to fix LNK2019. My code is below, but I just cannot understand how anything related to LNK2019 from Microsoft's help center applies to it. GRRRRRR. The error says 1>Lab Four.obj : error LNK2019: unresolved external symbol "void __cdecl highLowReport(class weatherStation * const,int)" (?highLowReport@@YAXQAVweatherStation@@H@Z) referenced in function _main 1>Lab Four.obj :...
0
8316
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8833
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8737
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8509
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8610
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7345
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4327
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2735
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1730
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.