test(void *data) vs test(void &data)

S

Skybuck Flying

Hello,

I just came across something strange.

Prototypes for routines:

1: void test(void *data)
2: void test(void &data)

The first one does compile in visual studio 2010 and the second does not.

They both seem conceptually the same, like untyped variable data in Delphi,
yet the first one is allowed and the second is not allowed.

Isn't that strange ?! ;) :)

Seems like case 2 is not yet implemented, either in the c/c++ language rules
or in the compiler ?! ;)

Bye,
Skybuck.
 
S

Skybuck Flying

Also I had to convert "void test( void *data)" to Delphi.

My first conversion was:

procedure test( data : pointer );

The documentation of the test function seems to indicate that this function
returns all kinds of pointers, so it's like a call by reference call.

So I am starting to wonder if I perhaps should change it to something more
convenient like:

procedure test( var data );

This also explains my first/original posting.

I was trying out c/c++ to see if void test( void &data ) would be
valid/legal but to my surprise it was not.

So now I am wondering if it's safe to convert:

void test( void *data )

to

procedure test( var data );

I don't want no strange stack problems or access violations or anything like
that, so I have to make sure it's 100% the same and safe ?!?

The convenience would be nice to have though...

Bye,
Skybuck.
 
P

Paul

Skybuck Flying said:
Hello,

I just came across something strange.

Prototypes for routines:

1: void test(void *data)
2: void test(void &data)

The first one does compile in visual studio 2010 and the second does not.

They both seem conceptually the same, like untyped variable data in
Delphi, yet the first one is allowed and the second is not allowed.

Isn't that strange ?! ;) :)

Seems like case 2 is not yet implemented, either in the c/c++ language
rules or in the compiler ?! ;)

A reference must always refer to an object, and you cannot have an object of
type void.
You can have a reference to a void pointer though.

void test(void* &data){ data = new double[12];}

void* p=0;
test(p);

p now points to 12x doubles .
 
S

Skybuck Flying

Does this mean C is more strongly typed than Pascal/Delphi ???

In other words:

Delphi is more weakly typed than C ?!?

Many people believe it's the other way around.

Yet the following example proves Delphi is more relaxed/weaker typed:

Unless something else is going on underneath ?!? Therefore I worry the
generated code/stack/parameter calling, might not be compatible ?!?

Pascal/Delphi and C/C++ are supposed to be binary compatible to a certain
extent.

So I suspect Delphi might do something different than C/C++ to make it work,
then again perhaps C/C++ is more limited.

So I am not sure what is going on underneath... I guess I will have to start
inspecting assembler instructions to see what's going on.

Even if the reference as you call/mention it points to an int in C it's
still not possible.

Delphi can do the following:

// *** Begin of Test Program ***:

program TestProgram;

{$APPTYPE CONSOLE}

uses
SysUtils;

const
value : integer = 666;
c : pointer = @value;

procedure test( var data );
begin
pointer(data) := c;
end;

procedure Main;
var
p : ^integer;
begin
test( p );
writeln( 'p^: ', p^ );
end;

begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.

// *** End of Test Program ***

Bye,
Skybuck.
 
S

Skybuck Flying

Equivalent C program does not compile, please check if it does not in your
compiler:

int value = 666;
void *c = &value;

void test(void *data)
{
(void *)(*data) = c;
}

int main()
{
int *p;

test( &p );

printf("*p: %d \n", *p );
}


How strange...

Bye,
Skybuck.
 
S

Skybuck Flying

"Paul" wrote in message

Skybuck Flying said:
Hello,

I just came across something strange.

Prototypes for routines:

1: void test(void *data)
2: void test(void &data)

The first one does compile in visual studio 2010 and the second does not.

They both seem conceptually the same, like untyped variable data in
Delphi, yet the first one is allowed and the second is not allowed.

Isn't that strange ?! ;) :)

Seems like case 2 is not yet implemented, either in the c/c++ language
rules or in the compiler ?! ;)

"
A reference must always refer to an object, and you cannot have an object of
type void.
You can have a reference to a void pointer though.

void test(void* &data){ data = new double[12];}

void* p=0;
test(p);

p now points to 12x doubles .
"

You should test it first, I doubt your code works.

Better yet, look at the C test program provided and try to get it working,
whatever way you can without reasonable scope of the problem/goal/delphi
equivalent.

Bye,
Skybuck.
 
S

Skybuck Flying

"Skybuck Flying" wrote in message



"Paul" wrote in message

Skybuck Flying said:
Hello,

I just came across something strange.

Prototypes for routines:

1: void test(void *data)
2: void test(void &data)

The first one does compile in visual studio 2010 and the second does not.

They both seem conceptually the same, like untyped variable data in
Delphi, yet the first one is allowed and the second is not allowed.

Isn't that strange ?! ;) :)

Seems like case 2 is not yet implemented, either in the c/c++ language
rules or in the compiler ?! ;)

* correction within

"
A reference must always refer to an object, and you cannot have an object of
type void.
You can have a reference to a void pointer though.

void test(void* &data){ data = new double[12];}

void* p=0;
test(p);

p now points to 12x doubles .
"

You should test it first, I doubt your code works.

Better yet, look at the C test program provided and try to get it working,
whatever way you can within (*) reasonable scope of the problem/goal/delphi
equivalent.

Bye,
Skybuck.
 
P

Paul

Skybuck Flying said:
Equivalent C program does not compile, please check if it does not in your
compiler:

int value = 666;
void *c = &value;

void test(void *data)
{
(void *)(*data) = c;
}
This function body should be :
data = c;
You cannot dereference a void pointer.

But data would be a copy of the original pointer, to pass the pointer by
reference change it to:
void test(void* &data){
data=c;
}
int main()
{
int *p;

test( &p );
This passes the address of the pointer p, which has the type int** (pointer
to a pointer) and is not compatable with the function parameter.
Change it to:
test(p);
printf("*p: %d \n", *p );
}


How strange...
HTH
 
P

Paul

Skybuck Flying said:
Skybuck Flying said:
Hello,

I just came across something strange.

Prototypes for routines:

1: void test(void *data)
2: void test(void &data)

The first one does compile in visual studio 2010 and the second does not.

They both seem conceptually the same, like untyped variable data in
Delphi, yet the first one is allowed and the second is not allowed.

Isn't that strange ?! ;) :)

Seems like case 2 is not yet implemented, either in the c/c++ language
rules or in the compiler ?! ;)

* correction within

"
A reference must always refer to an object, and you cannot have an object
of
type void.
You can have a reference to a void pointer though.

void test(void* &data){ data = new double[12];}

void* p=0;
test(p);

p now points to 12x doubles .
"

You should test it first, I doubt your code works.
It works ok.
 
S

Skybuck Flying

Ok,

Now I understand sort of... but it's a bit confusing... I guess this pretty
much proves C is a bad language.

It's all about where the space is placed.

I guess the function should be written and interpreted as follows:

1: void test( void* data )

instead of

2: void test( void *data )

Interpretation of 1: call by value passing a void pointer.

Interpretation of 2: call by reference passing a void (which is not
allowed).

One could also argue that C programmer who write 2: test is a bad programmer
;)

I shall point this out to the programmer in question ;)

Bye,
Skybuck.
 
P

Paul

Skybuck Flying said:
Ok,

Now I understand sort of... but it's a bit confusing... I guess this
pretty much proves C is a bad language.

It's all about where the space is placed.

I guess the function should be written and interpreted as follows:

1: void test( void* data )

instead of

2: void test( void *data )

Interpretation of 1: call by value passing a void pointer.

Interpretation of 2: call by reference passing a void (which is not
allowed).

One could also argue that C programmer who write 2: test is a bad
programmer ;)

I shall point this out to the programmer in question ;)
A pointer can be declared as :

int* p;
or
int *p;

Both are the same its just a case of programming style.
 
A

Angel

["Followup-To:" header set to comp.lang.c.]
Ok,

Now I understand sort of... but it's a bit confusing... I guess this pretty
much proves C is a bad language.

It's all about where the space is placed.

I guess the function should be written and interpreted as follows:

1: void test( void* data )

instead of

2: void test( void *data )

Interpretation of 1: call by value passing a void pointer.

Interpretation of 2: call by reference passing a void (which is not
allowed).

In C, all function parameters are always passed by value. It's up to the
programmer to pass a pointer value to the function if callback is
needed.
One could also argue that C programmer who write 2: test is a bad programmer
;)

Actually 2 is the better form, because

int* foo, bar;

will not have the effect you think it does.
I shall point this out to the programmer in question ;)

If you don't actually know C, I'd recommend against that. You'll make
yourself look like a fool.
 
S

Skybuck Flying

"Paul" wrote in message

Skybuck Flying said:
Skybuck Flying said:
Hello,

I just came across something strange.

Prototypes for routines:

1: void test(void *data)
2: void test(void &data)

The first one does compile in visual studio 2010 and the second does not.

They both seem conceptually the same, like untyped variable data in
Delphi, yet the first one is allowed and the second is not allowed.

Isn't that strange ?! ;) :)

Seems like case 2 is not yet implemented, either in the c/c++ language
rules or in the compiler ?! ;)

* correction within

"
A reference must always refer to an object, and you cannot have an object
of
type void.
You can have a reference to a void pointer though.

void test(void* &data){ data = new double[12];}

void* p=0;
test(p);

p now points to 12x doubles .
"

You should test it first, I doubt your code works.

"
It works ok.
"

No it does not you are cheating.

try:

int *p=0;

Also allocating from within the routine is kinda lame and easy... try
outside.

Bye,
Skybuck.
 
J

James

Skybuck Flying said:
Equivalent C program does not compile, please check if it does not in your
compiler:

int value = 666;
void *c = &value;

void test(void *data)
{
(void *)(*data) = c;
}

int main()
{
int *p;

test( &p );

printf("*p: %d \n", *p );
}


int value = 666;
void* c = &value;


void test(void* data)
{
*((void**)data) = c;
}


int main(void)
{
int *p;
test( &p );
printf("*p: %d \n", *p );
}
 
S

Skybuck Flying

"Paul" wrote in message

Skybuck Flying said:
Ok,

Now I understand sort of... but it's a bit confusing... I guess this
pretty much proves C is a bad language.

It's all about where the space is placed.

I guess the function should be written and interpreted as follows:

1: void test( void* data )

instead of

2: void test( void *data )

Interpretation of 1: call by value passing a void pointer.

Interpretation of 2: call by reference passing a void (which is not
allowed).

One could also argue that C programmer who write 2: test is a bad
programmer ;)

I shall point this out to the programmer in question ;)
A pointer can be declared as :

"
int* p;
or
int *p;

Both are the same its just a case of programming style.
"

If it's the same then the program should work.

Yet it does not work.

Perhaps I can figure it out... but don't count on it.

Bye,
Skybuck.
 
S

Skybuck Flying

Ok,

I finally figured out what was wrong by replacing it with an int *p;

Apperently the problem is with the way C requires typecasts to be made.

Apperently it's not possible to typecast a pointer derefence immediately.

Example:

(void *)(*p) = (int *)(*p);

^ This is not allowed, or has different meaning, probably trying to typecast
what it's pointing to.

What needs to happen is the following:

*(void *)(p) = *(int *)(p);

First typecast variable itself to a new pointer type, then dereference it.

Parenthesis required.

Following program is Delphi equivalent:

Something special is apperently happing.

Address is taking of P and is pushed toward *data which itself is a pointer
to something.

Data is already pointing towards P.

Which is kinda strange.

But this is probably because of the & operator.

Had I written test( p ) then it would make sense the wrong code I wrote.

But test( &p ) <- already creates a pointer.

test(void *p );

^ Can now be a single pointer or double pointer it depends on the call.

The call is &p so it's a pointer pointer.

// VoidPointerVsVoidPointer.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"

int value = 666;

void *c;

void test( void *data )
{

*(void **)(data) = c;
}



int _tmain(int argc, _TCHAR* argv[])

{

void *p;

c = &value;

p = NULL;

test( &p );


if (p != NULL)

{

printf( "*p: %d \n", *(int *)(p) );

}

printf("wait \n");

return 0;

}

Now it works.

(I'm a bit annoyed at moment, but it has nothing to do with C, something
else annoyed me... though this is kinda shitty too ! ;) =D)

But nice to see it solved.

Bye,
Skybuck :)
 
S

Skybuck Flying

Time to clean up this mess and to sum things up:

The API has the following similar function:

void test( void *data );

The documentation mentions something about pointers but it's not terribly
clear about it.

So this function can now be called in two ways:

SomePointerType p;

case 1: test( p );
case 2: test( &p );

From the C prototype it is not clear which call type should be used.

This is exactly what C is a bad language and what I did not choose to
program in it 15 years ago.

Case 1 is C's call by value technique.
Case 2 is C's call by reference technique.

Both are valid call methods.

Without further/proper API documentation it is now impossible to determine
which call type is the correct call.

Bye,
Skybuck.
 
S

Skybuck Flying

The API documentation says the following:

"Returns in *data".

Usually "returns" means call by reference. So it could be ment here as well.

However it can also be interpreted as "returns data inside the data
structure/memory pointed to by *data".

For now I shall assume "call by reference" is ment, because a size parameter
is missing, though there is an attribute parameter which could still be an
indirect way of issueing the size.

Bye,
Skybuck.
 
S

Skybuck Flying

It's kinda interesting to note that I already wrote the api as "call by
reference" in Delphi:

procedure test( var data : pointer );

This doesn't really make Delphi any better than C because the API could
still return data inside the memory structure pointed towards by data.

However then the "var" word could be left out... this was added by me
though, which offers more interpretation mistakes probabilities.

However I think I interpreted it correctly.

This means it's still not 100% sure what the API and the code behind it is
actually doing.

Nor is the question answered if var data without the pointer is equivalent.

Since any typed pointer type can be assigned to test it's not really
important if it's var data : pointer or var data.

var data : pointer would be a little bit more safe.

However there might be one problem. The API itself seems to use
integer/longwords for pointers as well... these integers have no real
meaning on host, but do have meaning on other computer.

So I will still like to be able to pass any variable to this routine.

However passing more data then a pointer or an integer would still be stupid
so it does offer some type checking protection.

For now I shall fall back to typecasts where necessary, and leave the
function as it is... Hopefully it is not used much.

Bye,
Skybuck.
 
S

Skybuck Flying

One solution is make two functions, one for each type.

Sub solution is: different name for each function

or

Other sub solution: overloaded version.

This way no typecasting needed which would be nice, and strong type
checking.

Bye,
Skybuck.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top