Discussion:
test(void *data) vs test(void &data)
(too old to reply)
Skybuck Flying
2011-06-18 20:34:21 UTC
Permalink
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.
Skybuck Flying
2011-06-18 20:39:57 UTC
Permalink
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.
Paul
2011-06-18 21:30:34 UTC
Permalink
Post by Skybuck Flying
Hello,
I just came across something strange.
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 .
Skybuck Flying
2011-06-18 22:10:43 UTC
Permalink
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.
Skybuck Flying
2011-06-18 22:17:17 UTC
Permalink
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.
Paul
2011-06-18 22:30:46 UTC
Permalink
Post by Skybuck Flying
Equivalent C program does not compile, please check if it does not in your
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;
}
Post by Skybuck Flying
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);
Post by Skybuck Flying
printf("*p: %d \n", *p );
}
How strange...
HTH
Skybuck Flying
2011-06-18 22:36:02 UTC
Permalink
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.
Paul
2011-06-18 22:39:17 UTC
Permalink
Post by 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.
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.
Skybuck Flying
2011-06-18 22:53:12 UTC
Permalink
Post by 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.
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.
Skybuck Flying
2011-06-18 23:06:05 UTC
Permalink
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 :)
Skybuck Flying
2011-06-18 23:12:54 UTC
Permalink
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.
Skybuck Flying
2011-06-18 23:21:37 UTC
Permalink
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.
Skybuck Flying
2011-06-18 23:29:16 UTC
Permalink
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.
Skybuck Flying
2011-06-18 23:31:26 UTC
Permalink
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.
Skybuck Flying
2011-06-18 23:39:02 UTC
Permalink
This also seemed to be a very special api ;)

Therefore I am going to give it a very special treatment ! ;) =D LOL.

Problem is probably going to be solved nicely ! ;) =D

Bye,
Skybuck =)
Skybuck Flying
2011-06-20 16:17:44 UTC
Permalink
I shall round up/put a closure on this topic with one last final nice
posting (perhaps for noobies having to choose a language or experts trying
to understand the differences between the languages):
(Unless more reactions/replies come into it ;) but I would prefer if there
weren't any because I like to close this topic now.)

The difference is actually:

1. Pascal has call by value and call by reference.
2. C only has call by value.

Because of limitation 2, C programmers use the pointer trick to pass the
address of a variable so it can be changed inside the routine, example:

1. C call by value (default):

void test( int a )
{
a = 5; // after routine exists, value is lost.
}

test( b );

2. C call by value (reference trick):

void test( int *a ) <- pointer to variable of integer trick.
{
*a = 5;
}

test( &b ); // <- address of variable trick.

For noobies/novice programmers this makes C a bad language since
noobies/novice programmers are still learning to design software codes and
will often need to change call by value to call by reference or vice versa
and then it becomes a hurdle to change all these call sites, not mention
confusion.

For experienced programmers it's also a reall burden to use * everywhere and
& everywhere, everywhere reference comes into play.

Passing real pointers and working with them becomes even more tricky and
requires even more stars/asterixes.

A very bad problem which was easily solved in pascal:

procedure test( var a : integer );
begin
a := 5;
end;

test( a );

^ No stupid symbols needed ! ;) Much user friendly and pretty much does the
same thing.

Why make things more difficult then absolutely necessary huh ?! ;) :) =D

Only thing I can imagine is very very very maybe it's easier to write a
"call by value compiler" than a "call by reference compiler" ?!? But does
sound a bit like bullshit to me ?! ;) :)

Bye,
Skybuck =D
Stephen Sprunk
2011-06-20 18:51:34 UTC
Permalink
Post by Skybuck Flying
I shall round up/put a closure on this topic with one last final nice
posting (perhaps for noobies having to choose a language or experts
(Unless more reactions/replies come into it ;) but I would prefer if
there weren't any because I like to close this topic now.)
1. Pascal has call by value and call by reference.
2. C only has call by value.
Because of limitation 2, C programmers use the pointer trick to pass the
address of a variable so it can be changed inside the routine, ...
That is roughly correct.
Post by Skybuck Flying
For noobies/novice programmers this makes C a bad language since
noobies/novice programmers are still learning to design software codes and
will often need to change call by value to call by reference or vice versa
and then it becomes a hurdle to change all these call sites, not mention
confusion.
"Bad" is in the eye of the beholder. It's how C works. Indeed, truly
understanding pointers is often the hardest thing about learning C.
However, they're a core feature of the language, and the sooner you
start learning, the sooner you'll "get" how C works.
Post by Skybuck Flying
For experienced programmers it's also a reall burden to use * everywhere
and & everywhere, everywhere reference comes into play.
An experienced programmer should rarely have problems with them, since
part of gaining said experience is learning to use pointers. That's
where the real power of C comes from.
Post by Skybuck Flying
Why make things more difficult then absolutely necessary huh ?! ;) :) =D
The basic philosophy of C is to expose the low-level operation of the
machine as much as possible and let the programmer, if desired, build
higher-level operations. If you only want to deal with higher-level
operations, then another language is probably more appropriate.
Post by Skybuck Flying
Only thing I can imagine is very very very maybe it's easier to write a
"call by value compiler" than a "call by reference compiler" ?!? But does
sound a bit like bullshit to me ?! ;) :)
One might consider what would be required to add "references" to a C
compiler. To borrow the syntax from C++, one would have this:

void test(int &a) {
a = 5;
}
...
int b = 0;
test(b); // b==5 after call returns

However, to implement this, the reality is that the compiler would end
up producing identical output to what it would produce if it were given
this:

void test(int *a) {
*a = 5;
}
...
int b = 0;
test(&b); // b==5 after call returns

So, the only advantage of allowing the former is that it is arguably
easier for novices to understand, but it doesn't actually add anything
to the language--and it breaks the decades-old rule that functions
cannot change their parameters, which means programmers must closely
examine the declaration of every function they call to determine whether
or not it uses references.

C++ had a good reason to add this syntactical sugar: to avoid
(potentially expensive) calls to copy constructors for pass-by-value
arguments. That reason does not apply to C; all that would be left is
pure syntactical sugar, and that goes against the philosophy above.

Also, if deceiving the caller as above is desired for some reason, you
_could_ accomplish that with a (rather evil) macro:

#define test(x) (test)(&x)
void (test)(int *a) {
*a = 5;
}
...
int b = 0;
test(b); // b==5 after call returns

However, that should never survive any decent code review, and I would
seriously question hiring someone who thought it was a good idea.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Skybuck Flying
2011-06-21 04:12:10 UTC
Permalink
Please stop the nonsense.

Call by reference in pascal has huge adventages compared to C.

You accidently delete one little asterix somewhere and you have a crisis ;)
:)

Bye,
Skybuck ;) =D
Stephen Sprunk
2011-06-21 12:56:03 UTC
Permalink
Post by Skybuck Flying
Call by reference in pascal has huge adventages compared to C.
Only for those, such as you, who don't really understand C.
Post by Skybuck Flying
You accidently delete one little asterix somewhere and you have a crisis
;) :)
No, if you accidentally delete one little asterisk someone, the compiler
warns you of a type mismatch, and you fix that and move on.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Skybuck Flying
2011-06-21 15:15:59 UTC
Permalink
Post by Skybuck Flying
Call by reference in pascal has huge adventages compared to C.
"
Only for those, such as you, who don't really understand C.
"

Nope, no asterixes needed = no extra bugs ! ;) =D
Post by Skybuck Flying
You accidently delete one little asterix somewhere and you have a crisis
;) :)
"
No, if you accidentally delete one little asterisk someone, the compiler
warns you of a type mismatch, and you fix that and move on.
"

Perhaps, perhaps not, totally depends on the situation.

Bye,
Skybuck.
Stephen Sprunk
2011-06-21 15:59:18 UTC
Permalink
Post by Stephen Sprunk
Post by Skybuck Flying
Call by reference in pascal has huge adventages compared to C.
"
Only for those, such as you, who don't really understand C.
"
Nope, no asterixes needed = no extra bugs ! ;) =D
In C, the asterisks are required if you are working with pointers.
They're part of the language, not bugs.
Post by Stephen Sprunk
Post by Skybuck Flying
You accidently delete one little asterix somewhere and you have a crisis
;) :)
"
No, if you accidentally delete one little asterisk someone, the compiler
warns you of a type mismatch, and you fix that and move on.
"
Perhaps, perhaps not, totally depends on the situation.
Please provide a counter-example, as I've never seen one. Perhaps a
compiler warning is a "crisis" to you, but not for someone with a decent
amount of experience and understanding of the language.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Skybuck Flying
2011-06-21 20:48:02 UTC
Permalink
Post by Stephen Sprunk
Post by Skybuck Flying
Call by reference in pascal has huge adventages compared to C.
"
Only for those, such as you, who don't really understand C.
"
Nope, no asterixes needed = no extra bugs ! ;) =D
"
In C, the asterisks are required if you are working with pointers.
They're part of the language, not bugs.
"

You acting dumb again, are you really that dumb ? ;) :)

Pascal doesn't need pointers for call by reference, thus no asterixes
needed, thus no bugs with asterixes ! ;) =D
Post by Stephen Sprunk
Post by Skybuck Flying
You accidently delete one little asterix somewhere and you have a crisis
;) :)
"
No, if you accidentally delete one little asterisk someone, the compiler
warns you of a type mismatch, and you fix that and move on.
"
Perhaps, perhaps not, totally depends on the situation.
"
Please provide a counter-example, as I've never seen one. Perhaps a
compiler warning is a "crisis" to you, but not for someone with a decent
amount of experience and understanding of the language.
"

Then you sure haven’t programmed a lot:

I made a nice example for you, not a single warning ! ;)

void **********p1; // take a guess how many stars are missing ! ;):) Good
luck ! =D
int *p2;
p1 = NULL;
p2 = NULL;

p2 = (int *)(p1);
p2 = (int *)(&p2);

Bye,
Skybuck.
Keith Thompson
2011-06-21 22:33:44 UTC
Permalink
Post by Stephen Sprunk
Post by Stephen Sprunk
Post by Skybuck Flying
Call by reference in pascal has huge adventages compared to C.
"
Only for those, such as you, who don't really understand C.
"
Nope, no asterixes needed = no extra bugs ! ;) =D
"
In C, the asterisks are required if you are working with pointers.
They're part of the language, not bugs.
"
You acting dumb again, are you really that dumb ? ;) :)
Pascal doesn't need pointers for call by reference, thus no asterixes
needed, thus no bugs with asterixes ! ;) =D
[...]

Everyone, please take a moment to consider whether feeding this
particular troll is a good use of your time and everyone else's
attention.

Thank you.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Skybuck Flying
2011-06-22 00:06:32 UTC
Permalink
Post by Stephen Sprunk
Post by Stephen Sprunk
Post by Skybuck Flying
Call by reference in pascal has huge adventages compared to C.
"
Only for those, such as you, who don't really understand C.
"
Nope, no asterixes needed = no extra bugs ! ;) =D
"
In C, the asterisks are required if you are working with pointers.
They're part of the language, not bugs.
"
You acting dumb again, are you really that dumb ? ;) :)
Pascal doesn't need pointers for call by reference, thus no asterixes
needed, thus no bugs with asterixes ! ;) =D
[...]

"
Everyone, please take a moment to consider whether feeding this
particular troll is a good use of your time and everyone else's
attention.
"

Lol sense when is stating the thruth trolling ?! ;) =D

You delirious ! ;) =D

Bye,
Skybuck ! ;) =DDDDD
Arivald
2011-06-22 09:35:56 UTC
Permalink
Post by Keith Thompson
Post by Stephen Sprunk
Post by Stephen Sprunk
Post by Skybuck Flying
Call by reference in pascal has huge adventages compared to C.
"
Only for those, such as you, who don't really understand C.
"
Nope, no asterixes needed = no extra bugs ! ;) =D
"
In C, the asterisks are required if you are working with pointers.
They're part of the language, not bugs.
"
You acting dumb again, are you really that dumb ? ;) :)
Pascal doesn't need pointers for call by reference, thus no asterixes
needed, thus no bugs with asterixes ! ;) =D
[...]
Everyone, please take a moment to consider whether feeding this
particular troll is a good use of your time and everyone else's
attention.
Maybe we should hire Witcher, to take case of this monster ;-)
--
Arivald
Mark Storkamp
2011-06-21 13:20:17 UTC
Permalink
Post by Skybuck Flying
Please stop the nonsense.
Call by reference in pascal has huge adventages compared to C.
You accidently delete one little asterix somewhere and you have a crisis ;)
:)
I want one of those languages where if you accidently delete something
the compiler guesses what you meant and fixes it for you.

Some people just are not able to grasp (grok?) C well enough to
effectively program with it. Others are not meant to program at all.
Skybuck Flying
2011-06-21 15:18:12 UTC
Permalink
Post by Skybuck Flying
Please stop the nonsense.
Call by reference in pascal has huge adventages compared to C.
You accidently delete one little asterix somewhere and you have a crisis ;)
:)
"
I want one of those languages where if you accidently delete something
the compiler guesses what you meant and fixes it for you.
"
Try pascal:

begi

en

^ obvious what's missing there.

Also with call by reference no asterixes needed, so no asterixes can get
lost ! ;) =D

"
Some people just are not able to grasp (grok?) C well enough to
effectively program with it. Others are not meant to program at all.
"

As long as software is writing by humans there will be 1 bug per 10 lines of
code at least, that includes you ! ;) =D

Plus the rare occasional fok-up of accidently deleting something, then it's
nice to have pascal instead of c/c++.

I will fix such an accidently delete + save, in 1 second or so, you'll be
spending 1 hour trying to find that missing * or that missing } or that
missing { ;)

Bye,
Skybuck =D
Arivald
2011-06-21 13:59:17 UTC
Permalink
Post by Stephen Sprunk
Post by Skybuck Flying
I shall round up/put a closure on this topic with one last final nice
posting (perhaps for noobies having to choose a language or experts
(Unless more reactions/replies come into it ;) but I would prefer if
there weren't any because I like to close this topic now.)
1. Pascal has call by value and call by reference.
No, there is no references in pascal. There are constructs which works
like C++ reference, but under many different names.

For example, parameters passed using "var" (always) and "const"
(possibly, if it is faster than non-reference pasing) are passed by
reference. Specifically only pointer to variable is passed.
Sometimes this passing methods are called "passing by reference",
although it is not exactly correct.

Objects (TObject descandants), string, Variant and other automated types
are references itself. They are passed by value (if without "var" or
"const"), but because they are references, it effectively works like
passing by reference.
Post by Stephen Sprunk
Post by Skybuck Flying
2. C only has call by value.
Yes and no.
Passed pointer is value, but it is also reference to other value.
Post by Stephen Sprunk
Post by Skybuck Flying
Because of limitation 2, C programmers use the pointer trick to pass the
address of a variable so it can be changed inside the routine, ...
It is no limitation. it is no trick! It is fundamental way how computer
programs works! In assembler You also can pass copy of value, or pointer
to same value.
Post by Stephen Sprunk
Post by Skybuck Flying
For noobies/novice programmers this makes C a bad language since
noobies/novice programmers are still learning to design software codes and
will often need to change call by value to call by reference or vice versa
and then it becomes a hurdle to change all these call sites, not mention
confusion.
"Bad" is in the eye of the beholder. It's how C works. Indeed, truly
understanding pointers is often the hardest thing about learning C.
However, they're a core feature of the language, and the sooner you
start learning, the sooner you'll "get" how C works.
Learning pointers in Delphi is same problem.
Post by Stephen Sprunk
Post by Skybuck Flying
For experienced programmers it's also a reall burden to use * everywhere
and& everywhere, everywhere reference comes into play.
An experienced programmer should rarely have problems with them, since
part of gaining said experience is learning to use pointers. That's
where the real power of C comes from.
Post by Skybuck Flying
Why make things more difficult then absolutely necessary huh ?! ;) :) =D
Exactly. What idiot design Delphi objects. You can't pass this objects
by value (making copy). You can't return then by value. There is no
standard way to make copy of object (what a real pain!). There is no way
to have object on stack (automatic destruction on stack rewinding). And
lot more...
Post by Stephen Sprunk
The basic philosophy of C is to expose the low-level operation of the
machine as much as possible and let the programmer, if desired, build
higher-level operations. If you only want to deal with higher-level
operations, then another language is probably more appropriate.
Like C++. Fast and safe (if You know what You doing), close to hardware.
Post by Stephen Sprunk
Post by Skybuck Flying
Only thing I can imagine is very very very maybe it's easier to write a
"call by value compiler" than a "call by reference compiler" ?!? But does
sound a bit like bullshit to me ?! ;) :)
One might consider what would be required to add "references" to a C
void test(int&a) {
a = 5;
}
...
int b = 0;
test(b); // b==5 after call returns
However, to implement this, the reality is that the compiler would end
up producing identical output to what it would produce if it were given
void test(int *a) {
*a = 5;
}
...
int b = 0;
test(&b); // b==5 after call returns
So, the only advantage of allowing the former is that it is arguably
easier for novices to understand, but it doesn't actually add anything
to the language--and it breaks the decades-old rule that functions
cannot change their parameters, which means programmers must closely
examine the declaration of every function they call to determine whether
or not it uses references.
C++ had a good reason to add this syntactical sugar: to avoid
(potentially expensive) calls to copy constructors for pass-by-value
arguments.
Speed is no main issue for copy constructor. Issue is: You need to make
copy to pass it to copy constructor... And to make copy compiler need to
call copy constructor first ;-) So You need to make copy to be able to
make copy ;-)

Of course they may make copy ctor get pointer, but using reference is
much safer.

Reference parameter have one huge advantage over pointer: it can't be
NULL. It means no NULL checking, with most advantages of using pointer.
It is why they design references for C++. Without references most of STL
will be not possible.
Post by Stephen Sprunk
That reason does not apply to C; all that would be left is
pure syntactical sugar, and that goes against the philosophy above.
C may also benefit from non-NULL property of references.
--
Arivald
jacob navia
2011-06-21 14:07:33 UTC
Permalink
Post by Arivald
C may also benefit from non-NULL property of references.
Yes!

That is why the lcc-win C compiler implements references.
Keith Thompson
2011-06-21 15:06:38 UTC
Permalink
[...]
Post by Arivald
Post by Skybuck Flying
1. Pascal has call by value and call by reference.
No, there is no references in pascal. There are constructs which works
like C++ reference, but under many different names.
He didn't say Pascal has references; he said Pascal has call by
reference. Which it does; that's what "var" parameters are.
Post by Arivald
For example, parameters passed using "var" (always) and "const"
(possibly, if it is faster than non-reference pasing) are passed by
reference. Specifically only pointer to variable is passed.
Sometimes this passing methods are called "passing by reference",
although it is not exactly correct.
I think it is, given the usual (not necessarily language-specific)
meaning of the phrase "call by reference" or, as I prefer to call it,
"pass by reference".
Post by Arivald
Objects (TObject descandants), string, Variant and other automated types
are references itself. They are passed by value (if without "var" or
"const"), but because they are references, it effectively works like
passing by reference.
You seem to be talking about some dialect of Pascal, not standard
Pascal itself.
Post by Arivald
Post by Skybuck Flying
2. C only has call by value.
Yes and no.
Passed pointer is value, but it is also reference to other value.
The C language only has pass by value. Features of the language can
be used to implement (or, if you prefer, emulate) pass by reference.

[...]
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Stephen Sprunk
2011-06-19 08:06:18 UTC
Permalink
Post by Skybuck Flying
Now I understand sort of... but it's a bit confusing... I guess this
pretty much proves C is a bad language.
No, this just proves you don't understand it and therefore have no
standing to make any judgment about how "bad" it might be.
Post by Skybuck Flying
It's all about where the space is placed.
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).
Incorrect. The two are identical: they both declare a function
returning void with one parameter named data of type pointer-to-void.
Post by Skybuck Flying
One could also argue that C programmer who write 2: test is a bad
programmer ;)
Actually, the latter is better style. If you don't understand why,
that's just more evidence that you don't understand C.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Skybuck Flying
2011-06-19 13:57:02 UTC
Permalink
This just makes it worse.

This means the call by reference call has to be written as:

void test (void ** data);

test( p );

which would be the same as the other example.

That's a whole lot of stars for something which is really easily implemented
in pascal and does exactly the same thing and a whole lot user friendly.

No need to type *data everywhere.

You C programmers just like making things unnecessarily difficult for
yourself, or you don't even know it... which makes you kinda look retarded.

Give pascal a try if you never haven't ! ;) =D

Bye,
Skybuck =D
Stephen Sprunk
2011-06-19 18:41:37 UTC
Permalink
Post by Skybuck Flying
This just makes it worse.
What just makes what worse? You didn't quote anything, so we don't know
the context of your statement.
Post by Skybuck Flying
void test (void ** data);
test( p );
That depends on what you're trying to accomplish.
Post by Skybuck Flying
which would be the same as the other example.
What other example?
Post by Skybuck Flying
You C programmers just like making things unnecessarily difficult for
yourself, or you don't even know it... which makes you kinda look retarded.
It only looks difficult to you because you (quite obviously) don't
understand it.
Post by Skybuck Flying
Give pascal a try if you never haven't ! ;) =D
My first real language (IMHO, BASIC doesn't count) was Pascal, and I was
a professional Delphi programmer for a while. I resisted learning C for
years, but once I finally understood it, I never went back.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Skybuck Flying
2011-06-20 05:16:18 UTC
Permalink
I do understand it now.

I still think it sucks bad.

Bye,
Skybuck.
Skybuck Flying
2011-06-18 22:25:32 UTC
Permalink
Post by Skybuck Flying
Hello,
I just came across something strange.
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.
Skybuck Flying
2011-06-18 22:26:29 UTC
Permalink
Post by Skybuck Flying
Hello,
I just came across something strange.
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.
Paul
2011-06-18 22:35:18 UTC
Permalink
Post by Skybuck Flying
Post by Skybuck Flying
Hello,
I just came across something strange.
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.
Skybuck Flying
2011-06-18 22:49:07 UTC
Permalink
Post by Skybuck Flying
Post by Skybuck Flying
Hello,
I just came across something strange.
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.
Keith Thompson
2011-06-18 23:35:17 UTC
Permalink
Post by Skybuck Flying
I just came across something strange.
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 ?! ;) :)
No.
Post by Skybuck Flying
Seems like case 2 is not yet implemented, either in the c/c++ language rules
or in the compiler ?! ;)
The second form appears to be a reference parameter, a feature that
C++ has and C doesn't. C and C++ are two different languages.

If you didn't know that, I suggest that your vague opinion that they
"both seem conceptually the same" isn't worth much.

But if you really want to know why something doesn't compile,
you should post a complete source file along with the actual error
messages.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Skybuck Flying
2011-06-19 03:45:55 UTC
Permalink
So are you claiming that:

void test( void &data )
{
}

Does compile in either C or C++ but does not compile in either C or C++ ?

Just stuff it into a console program yourself.

Full source not needed.

Bye,
Skybuck.
Paul
2011-06-19 06:33:15 UTC
Permalink
Post by Skybuck Flying
void test( void &data )
{
}
Does compile in either C or C++ but does not compile in either C or C++ ?
Just stuff it into a console program yourself.
Full source not needed.
No

void test( void* &data){;}
Stephen Sprunk
2011-06-19 08:03:21 UTC
Permalink
Post by Skybuck Flying
I just came across something strange.
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 ?! ;)
& is not a valid type specifier in C, period.

It might or might not be valid in C++, but since you haven't
cross-posted this to a C++ newsgroup, responding to that would be off-topic.

C and C++ are different languages. There is no language called "C/C++".

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Skybuck Flying
2011-06-19 14:04:01 UTC
Permalink
I did cross post it to c++.

Take your own conclusions.

Bye,
Skybuck.
Skybuck Flying
2011-06-19 14:05:26 UTC
Permalink
Also what do you think the ++ hint at in c++ ?!?

Behehehehehehehe.

You response is so stupid I am not even going to respond to it because it's
far below my level of what I will expect.

Bye,
Skybuck.
Jamie
2011-06-19 14:53:54 UTC
Permalink
Post by Stephen Sprunk
Post by Skybuck Flying
I just came across something strange.
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 ?! ;)
& is not a valid type specifier in C, period.
It might or might not be valid in C++, but since you haven't
cross-posted this to a C++ newsgroup, responding to that would be off-topic.
C and C++ are different languages. There is no language called "C/C++".
S
Actually, I've done C/C++ for years. You may have a little miss
understanding here.

C++ is everything C can do with added fluff, which is why they gave
it the "++" extension in the first place.

C++ is an extension to C language, which is why you see the C/C++ all
over the place. They are not two different languages. C++ has the Class
model and a few other things that stands above C but it can also do what
C does.

I wouldn't use a C++ compiler that refused to support the basic
operations of C language..

Sorry, but so many get steered off on the wrong road when it comes to
the history of languages..

It's the same in delphi land. Delphi isn't the language, it's the
package over all, the language base is enhanced Pascal and thus follows
the stream of that. Just because it has classes,objects and others that
Pascal did not have, does not change the fact that it is still a Pascal
oriented language and C++ is still a C oriented language.

Jamie
Skybuck Flying
2011-06-19 15:08:57 UTC
Permalink
Well for once in my life, you actually make me happy ! ;) =D

Bye,
Skybuck =D
Post by Stephen Sprunk
Post by Skybuck Flying
I just came across something strange.
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 ?! ;)
& is not a valid type specifier in C, period.
It might or might not be valid in C++, but since you haven't
cross-posted this to a C++ newsgroup, responding to that would be off-topic.
C and C++ are different languages. There is no language called "C/C++".
S
Actually, I've done C/C++ for years. You may have a little miss
understanding here.

C++ is everything C can do with added fluff, which is why they gave
it the "++" extension in the first place.

C++ is an extension to C language, which is why you see the C/C++ all
over the place. They are not two different languages. C++ has the Class
model and a few other things that stands above C but it can also do what
C does.

I wouldn't use a C++ compiler that refused to support the basic
operations of C language..

Sorry, but so many get steered off on the wrong road when it comes to
the history of languages..

It's the same in delphi land. Delphi isn't the language, it's the
package over all, the language base is enhanced Pascal and thus follows
the stream of that. Just because it has classes,objects and others that
Pascal did not have, does not change the fact that it is still a Pascal
oriented language and C++ is still a C oriented language.

Jamie
James Kuyper
2011-06-19 17:02:37 UTC
Permalink
Post by Jamie
Post by Stephen Sprunk
Post by Skybuck Flying
I just came across something strange.
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 ?! ;)
& is not a valid type specifier in C, period.
It might or might not be valid in C++, but since you haven't
cross-posted this to a C++ newsgroup, responding to that would be off-topic.
C and C++ are different languages. There is no language called "C/C++".
S
Actually, I've done C/C++ for years. You may have a little miss
understanding here.
C++ is everything C can do with added fluff, which is why they gave
it the "++" extension in the first place.
No, it is not. C has many features that render it incompatible with C,
and not merely an extension of it. See Annex C of the the C++ standard
for a list. In the meantime, C has gone it's own way, adding many
features in C99 that are incompatible with C++ (while adding a few
features that make it more compatible).
Post by Jamie
C++ is an extension to C language, which is why you see the C/C++ all
over the place. They are not two different languages. C++ has the Class
model and a few other things that stands above C but it can also do what
C does.
I wouldn't use a C++ compiler that refused to support the basic
operations of C language..
The following is very carefully designed to make many different points
in a program that is as small as possible. I make no claim that it is an
example of good programming practice

It is syntactically valid code in both C and C++, conforms strictly to
the C99 standard, and is well-formed code according to both the C++98
and C++03 standards. It's behavior under C90 is technically undefined,
but only by reason of it's use of __cplusplus, an identifier which a C90
compiler could, in principle, have reserved for it's own incompatible
usage - but such compilers are rare, and probably non-existent.

You can compile and link both modules as C code, or as C++ code; the
resulting executables are guaranteed by the applicable standards to exit
with an failure status, for two entirely different sets of reasons,
depending upon which language is used (note that many compilers
automatically infer the language to be used from the extension on the
filename - you might need to rename the files to get them to actually
compile in one language rather than the other).

If you compile the first module with C, and the second with C++, it is
guaranteed to return a successful exit status. If C++ were really just
an extension to C, then what I've said about how this program's behavior
varies with the programming language would be impossible.

shared.h:
=========
#ifndef SHARED_H
#define SHARED_H

extern char tag;
extern int enumer[2];

typedef void voidvoid(void);

int Cnmtyp(void);
int Cfunc(voidvoid*);

#endif

First module:
=============
#ifdef __cplusplus
extern "C" {
#endif

#include "shared.h"

char tag = 0;

static int hidden(voidvoid *pfunc)
{
(*pfunc)();
tag = sizeof 'C' == sizeof(int);
return Cnmtyp() && enumer[0] && enumer[1];
}

int Cfunc(voidvoid* pfunc)
{
struct tag
{
enum { enumer, other } in;
int integer;
} out;

out.integer = sizeof(tag) == 1 && sizeof(enumer) == sizeof out.in;

return hidden(pfunc) && out.integer;
}

#ifdef __cplusplus
}
#endif

Second module:
==============
#ifdef __cplusplus
extern "C" {
#endif

#include "shared.h"

int enumer[2] = {0, 1};

static void Cppname_Cpptype(void)
{
enumer[0] = sizeof 'C' == 1;
return;
}

#ifdef __cplusplus
}
#endif

int Cnmtyp(void)
{
struct tag
{
enum { enumer, other } in;
int integer;
} out;

out.integer = sizeof(enumer) == 2 * sizeof(int);

return out.integer && sizeof(tag) == sizeof out;
}

static voidvoid Cppname_Ctype;

static void Cppname_Ctype(void) {
Cppname_Cpptype();
}

int main(void) {
return Cfunc(&Cppname_Ctype) && tag;
}

As an exercise for the student: explain precisely why three different
conditional expressions in the above code are guaranteed to have
different values in C and C++, and why two other conditionals will have
different values except in the unlikely case that sizeof(int)==1.
--
James Kuyper
Stephen Sprunk
2011-06-19 18:35:50 UTC
Permalink
Post by Jamie
Post by Stephen Sprunk
Post by Skybuck Flying
Seems like case 2 is not yet implemented, either in the c/c++ language
rules or in the compiler ?! ;)
& is not a valid type specifier in C, period.
It might or might not be valid in C++, but since you haven't
cross-posted this to a C++ newsgroup, responding to that would be off-topic.
C and C++ are different languages. There is no language called "C/C++".
Actually, I've done C/C++ for years. You may have a little miss
understanding here.
C++ is everything C can do with added fluff, which is why they gave it
the "++" extension in the first place.
They're still different languages.
Post by Jamie
C++ is an extension to C language,
It started out that way, but it is now specified in a separate standard
and is now sufficiently different that it isn't the same thing. In
fact, there is valid C code that is not valid C++ code--or has a
different meaning entirely.
Post by Jamie
I wouldn't use a C++ compiler that refused to support the basic
operations of C language..
Most, if not all, C++ compilers have a separate mode capable of
compiling C. That doesn't they're the same language, though. In fact,
that one has to invoke a separate mode is strong evidence they are
different languages. One of the most popular compilers, GCC, can also
compile Objective C, Java, Fortran and Ada; that doesn't mean those are
also all the same language.
Post by Jamie
Just because [Delphi] has classes,objects and others that Pascal did
not have, does not change the fact that it is still a Pascal oriented
language and C++ is still a C oriented language.
I am not disputing that C++ is a C-like or C-based language. So are C#
and Java, for that matter. They're still separate languages.

It's been too long since I've used Delphi to comment on its relation to
Pascal. I don't see what relevance that has to a discussion about
whether there is a single "C/C++" language, though.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Skybuck Flying
2011-06-20 05:20:12 UTC
Permalink
Hahahahaha !

So even if it were true what you were saying then that would mean

C and C++ are no longer compatible !

What a joke ! ;) =D

Bye,
Skybuck =D
Stephen Sprunk
2011-06-20 18:14:38 UTC
Permalink
Post by Skybuck Flying
Hahahahaha !
So even if it were true what you were saying then that would mean
Even if what were true? Since you didn't quote any context, I don't
know what you're referring to.
Post by Skybuck Flying
C and C++ are no longer compatible !
That is correct. There is a subset of both languages that is valid in
both, and a smaller subset that even means the same thing. However,
some C code is not valid C++ code, and a lot of C++ code is not valid C
code. That's why they're different languages--and why C++ is not merely
an "extension" of C as you claim.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Skybuck Flying
2011-06-21 04:13:44 UTC
Permalink
No this just means C/C++ is broken.

Find another language before it breaks your code even more ! ;) :)

Bye,
Skybuck =D
Arivald
2011-06-21 14:03:57 UTC
Permalink
Post by Skybuck Flying
I just came across something strange.
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 ?! ;)
& is not a valid type specifier in C, period.
It might or might not be valid in C++, but since you haven't
cross-posted this to a C++ newsgroup, responding to that would be off-topic.
C and C++ are different languages. There is no language called "C/C++".
Even in C++ You can't have untyped reference (reference to void).

So case 2 will never compile in C or C++.
--
Arivald
Skybuck Flying
2011-06-19 14:06:10 UTC
Permalink
(*) corrections ;) =D

"Skybuck Flying" wrote in message news:...

Also what do you think the ++ hint at in c++ ?!?

Behehehehehehehe.

Your (*) response is so stupid I am not even going to respond to it because
it's
far below my level of what I will accept(*).

Bye,
Skybuck.
Loading...