is c++ requirement to cast pointers(like the one returned frommalloc) redundant ?

R

Rafael Anschau

To me, it seems so, since it´s the job of the operator that
manipulates the pointer to know to what type the data in memory
belongs.

int *p=(int*)malloc(10*sizeof(int));

Would the language be much worse of without the need for (int*) ?

Rafael
 
R

red floyd

To me, it seems so, since it´s the job of the operator that
manipulates the pointer to know to what type the data in memory
belongs.

int *p=(int*)malloc(10*sizeof(int));

Would the language be much worse of without the need for (int*) ?

It isn't needed.

int *p = new int[10];

Even better would be using a vector.
 
R

Rolf Magnus

Rafael said:
To me, it seems so,
What?

since it´s the job of the operator that manipulates the pointer to know to
what type the data in memory belongs.

int *p=(int*)malloc(10*sizeof(int));

Don't use malloc in C++. Use the new operator. You won't need a cast there.
And if you need a cast, don't use C style casts. Always prefer one of the
C++ casts, in this case static_casst.
Would the language be much worse of without the need for (int*) ?

When you use C++ at it is supposed to be used, you should need casts only
rarely, mostly in low-level code. IMHO, it's good that C++ needs casts in
places like the above, forcing you to tell the compiler that you actually
want a potentially dangerous conversion to be done anyway. It should also
make you think if you really need the cast or maybe are doing something
wrong.
 
R

Rafael Anschau

Thanks for the answers, I am aware of the "efficient c++"
guidelines(new, vector etc), and no I don´t use malloc in C++. I was
helping to debug someone else´s code when I realized the reason it didn
´t compile was that the person was saving .cpp. And that in C++, you
need to cast malloc´s return. My doubt is if people agree/disagree
that need for cast in malloc is redundant. Magnus, I agree that
making it explicit forces you to check your assumptions, and that not
checking could get you into problems. That maybe the reason for it(I
looked up annotated c++ and didn´t find anything about it, but that´s
a good justification).

Thanks,

Rafael
 
I

Ian Collins

On 03/14/10 11:22 AM, Rafael Anschau wrote:

[Please don't top-post!]
> Thanks for the answers, I am aware of the "efficient c++"
> guidelines(new, vector etc), and no I don´t use malloc in C++. I was
> helping to debug someone else´s code when I realized the reason itdidn
> ´t compile was that the person was saving .cpp. And that in C++, you
> need to cast malloc´s return. My doubt is if people agree/disagree
> that need for cast in malloc is redundant. Magnus, I agree that
> making it explicit forces you to check your assumptions, and that not
> checking could get you into problems. That maybe the reason for it(I
> looked up annotated c++ and didn´t find anything about it, but that´s
> a good justification).

The cast isn't redundant. I fact it was added to C++ (you don't have to
cast in C) when C's automatic conversion from void* was removed.
 
R

Rafael Anschau

The cast isn't redundant.  I fact it was added to C++ (you don't have to
cast in C) when C's automatic conversion from void* was removed.

I guess I am the only one curious as to why someone would do that.
Maybe there´s a reason...

Rafael
 
R

Robert Fendt

I guess I am the only one curious as to why someone would do that.
Maybe there´s a reason...

Yes, there ist, and in fact Rolf already said it: C++ forces you
to be 'verbose' about your intent in several places where C does
not. The idea in general is that the compiler can give better
diagnostics if you tell it more about what you actually want to
achieve. This philosophy of increased semantic verbosity (i.e.,
"tell the compiler more about what you actually want to do") is
one of the main differences between C++ and C, support for OOP
and templates aside. (As a side effect, C++ is a considerably
"more strongly typed" language than C, and _that_ is in fact
what your example shows.)

However, the general diagnostics point aside, pointer conversion
between unrelated types (i.e., void* to int*) is --first of
all-- potentially a very dangerous thing. Thus it was decided
that C++ should not do it without explicitely being told so. And
that's a very sound design principle. C++ is not just an addon
to C (anymore): it is a language in its own right. Closely
related and painstakingly kept interoperable, yes, but
independent nevertheless. Asking "why is C++ different from C"
is a bit like asking why Java differs from C++, or why Ruby
differs from Python.

Regards,
Robert
 
R

Robert Fendt

But, you don;t have type safety anyway?

Yes, you *have*. In fact C++ could be called a strongly-typed
language with much better justification than C. However, C++ is
designed to be interoperable with C, which means that you can
effectively "disable" the type system, and this is where
explicit casting comes in.

Thus your code example show nothing more than the possibility to
tell the compiler "shut up, I know what I'm doing". Thus you
consciously and explicitely override the type system. However,
using this as "proof" for C++ providing no type safety that's
like loosening the seat-belt while driving, only to complain
about the car's safety if an accident gets you thrown out of the
window.

Regards,
Robert
 
R

Robert Fendt

I think that "strongly typed" and "type safety" is not
same thing? Im not native English speaker, so please clarify.

They are at least strongly related. You have type-safety in C++
in the sense that as long as you use C++'s type system, you can
be absolutely sure about a symbol's type. Casting to/from void*
explicitely turns the type system off temporarily, and yes, this
means that you loose type-safety. But you do not just loose it,
in fact you actively throw it away. Doing that and then saying
it was never there is non-sense, and that is what I meant.
Only way to interface other C compiler or other language
is through C. C++ doesn't provide means to make C++
library and provide C++ interface. You have to use C
interface.

I do not know if I understand your statement correctly. You seem
to say that it were not possible to write software libraries in
pure C++. Which is wrong. Just have a look at rather big
frameworks like wxWidgets or Qt. Object-oriented C++, not C.

It is tradition rather than a technical necessity for other
languages to provide C interfaces rather that C++. That, and
it's often much simpler to do. Add the fact that if you provide
a C interface, you provide a "common demoninator" for almost
every other language on the planet, because they more or less
all have C interoperability features, too. So if you provide a C
interface, the Java people can use it as well as Python
programmers, apart from 'just' C programmers. That said, there
are other possibilities (e.g., SWIG).

Regards,
Robert
 
J

James Kanze

On 03/14/10 11:22 AM, Rafael Anschau wrote:

[...]
The cast isn't redundant. I fact it was added to C++ (you
don't have to cast in C) when C's automatic conversion from
void* was removed.

Just a nit, but I think that the correct formulation in the last
phrase would be that "standard C's automatic conversion from
void* wasn't added to C". I don't have my copy of K&R1 handy,
but IIRC, pointers to different types didn't implicitly convert
in it (although---again, IIRC---there was a statement to the
effect that this wasn't enforced in current compilers).

C++ was originally developed before the C committee added void
and void* (the C committee adopted these from C), and it didn't
have the conversion. The conversion is an innovation of the C
committee, and not conform with the original intent in C. (It
may be supposed that Stroustrup was familiar with the original
intent in C when he invented void and void*, given that his boss
at the time was Brian Kernighan.)
 
J

James Kanze

I guess I am the only one curious as to why someone would do
that. Maybe there´s a reason...

The question isn't why someone would remove the conversion; if
it were a question of removal, it doubtlessly wouldn't have been
adopted for fear of breaking existing code. The question is why
one would add it in the first place, thus breaking what little
type safety already existed.
 
J

James Kanze

And thus spake Branimir Maksimovic <[email protected]>
Sat, 13 Mar 2010 23:49:01 +0100:
Yes, you *have*. In fact C++ could be called a strongly-typed
language with much better justification than C.

Neither are strongly typed, but the history of C++ has been
(partially) one of improving type safety. C++ introduced the
void* (which was later adopted into C) so that you didn't have
to use char* when you didn't know the type, for example: you
have to explicitly say that the type is unknown. And
originally, any conversion of void* to another pointer type
(except void const*, of course) did require a conversion. Not
requiring the explicit conversion is the innovation.

[For the rest, I think you've very effectively summed up the
situation.]
 
R

Robert Fendt

I don;t think so. You can;t provide type safe C++ interface that
can be used by other language. You have to first standardize
on binary level. Something like Microsoft COM but better.
*We need standardized C++ ABI*.

If you mean ABI, why don't you say ABI? "Interface" is a very
generic term with a multitude of meanings. However, sorry to
disappoint you, but there is no really standardised "C ABI"
either. Linking binary objects is more or less only and ever
guaranteed to work if you know exactly what compiler they were
created with (and preferrably use the corresponding linker).

That said, POSIX does define functions for C in order to enable
runtime loading (and there's equivalent functionality on
Windows), which essentially requires the existence of a 'minimal'
ABI on the particular OS you are working on. But whether that's
e.g. a.out or ELF based is not POSIX's concern, so again you do
*not* have a really standardised C ABI.
Problem is that crossing boundary between languages is
not type safe and all sorts of errors pass through.

And this is a problem of C++, how? This is *always* a problem,
and e.g. Java and C# have it, too. Different languages mean
incompatible concepts, that's natural, please do not compare
apples and oranges. Ever tried to intermix managed and native
C++ code while at the same time dealing with exceptions thrown
on either side?

Regards,
Robert
 
B

Bo Persson

Branimir said:
Problem is that when interfacing with void* you have to cast
all the time which is not necessary as user of library can pass
anything anyway. So it's just more verbose, but not useful
in practice.

But that's C code, not C++.

Templates solves the problem of returning the proper type, as shown by
the new operator. That way you don't need the totsally unsafe implicit
casting.


Bo Persson
 
J

Jorgen Grahn

Problem is that when interfacing with void* you have to cast
all the time which is not necessary as user of library can pass
anything anyway. So it's just more verbose, but not useful
in practice.
You can;t say don;t use malloc, use new, there are lot more
situations where void* is used and you can;t do anything about it.

Which (real-life) situations are that? Interfacing to C libraries
which use it: yes. I think I'd wrap such an API if I had to use it.
But other than that, I can't remember having used void* recently.

/Jorgen
 
J

James Kanze

Are you sure?

Yes, although I'll admit I'm working from memory here. My copy
of K&R 1 is in boxes at present, but I distinctly remember a
statement in it to the effect that you couldn't assign between
pointers to different types, although the current compilers
(this would be about 1980) didn't enforce this rule.
bmaxa@maxa:~$ gcc -std=c89 ts.c -o ts
ts.c: In function ‘main’:
ts.c:5: warning: initialization from incompatible pointer type
bmaxa@maxa:~$ cat ts.c
int main(void)
{
int a=10;
int *pa = &a;
float *p = pa;
return 0;
}

This is clearly illegal in ISO C, and was also illegal according
to K&R 1. The fact that early compilers didn't enforce the
rule, however, and that people violated a lot, probably explains
why gcc chooses to give a warning instead of an error.

Note too that the original discussion here concerned void*. The
keyword void appeared first in C++, and there have never been
any implicit conversions from void* in C++. Not even back in
the days when C didn't have the keyword void. (The issues are
far from trivial. The basic problem is that you cannot cleanly
support dynamic allocation in a strongly typed language unless
it is part of the languge, and not just a library plug-in. In
C++, of course, new is part of the language, and there's no
problem, but in C...)
 
B

Bart van Ingen Schenau

You can be sure that James knows what he is talking about.
Also note that we are talking about the early history of both C and C+
+ here (early to mid 1980's), when neither language was governed by an
international standard.
bmaxa@maxa:~$ g++ -std=c++98 ts.c -o ts
ts.c: In function ‘int main()’:
ts.c:5: error: cannot convert ‘int*’ to ‘float*’ in initialization
bmaxa@maxa:~$

C++ compiler gives error, while C compiler gives a warning.
That's a difference.

It is a difference in choices made by the compiler writers. Neither
the C nor the C++ standard requires an error. In fact, neither
standard ever requires that a compiler gives an error[1]. The
standards only require a diagnostic message and the formatting of such
messages is completely left to the compiler writers, even as the
further consequences (successful compilation, continue but don't
create an executable, abort compilation, etc.).
Since C is older then C++, not requiring
explicit conversion is not innovation rather opposite.

Although the first version of C appeared before C++, there was quite a
bit of transfer of ideas between the two languages before C was
stanardised.
For example, the keywords const and void first appeared in C++ and
were later taken over into C.

When interfacing C code (including malloc) you have to be
more verbose and you don;t get warnings. If you could do
implicit conversion, compiler would riddle code with warnings, for
maintainers. My English is not good, but I think now point
is understandable.

I am sorry, but I don't see your point.

This code will not give you any warnings in C, but it is still very
wrong:
int main(void)
{
int a=10;
int *pa = &a;
void *p = pa;
float *pfa = p;
return 0;
}

In C++, you will get a warning for the dangerous conversion from void*
to float* and you have to use an ugly cast, which stands out like a
red flag, to silence the compiler.

Bart v Ingen Schenau

[1] There is one exception, if my memory serves me right: The #error
preprocessor directive.
 

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
474,148
Messages
2,570,838
Members
47,385
Latest member
Joneswilliam01

Latest Threads

Top