Vikas Verma
Vikas Verma

Reputation: 3706

What is the exact meaning of "type-safety" in C++?

According to this site:

You cannot implicitly assign from a void* to any other type. For instance, the following is perfectly valid in C (in fact, it's arguably the preferable way of doing it in C)

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

but it won't compile in C++.

The explanation from Bjarne Stroustrup himself is that this isn't type safe. What this means is that you can have a void* that points to anything at all, and if you then assign the address stored in that void* to another pointer of a different type, there isn't any warning at all about it.

Consider the following:

int an_int;
void *void_pointer = &an_int;
double *double_ptr = void_pointer;
*double_ptr = 5;
cout<<an_int<<endl;

When you assign *double_ptr the value 5, it's writing 8 bytes of memory, but the integer variable an_int is only 4 bytes. So when you prints the value of an_int variable, output will be 0 because according to 4 bytes compiler select least significant bits of 5(5.000..) that is 0.

In C++, forcing a cast from a void pointer makes the programmer pay attention to these things. So in that language implicitly type conversion from void * is forbidden to give stronger type safety.

but I am literally confused when I'd cast void * to double * in this example like:

int an_int;
void *void_pointer = &an_int;
double *double_ptr = (double *)void_pointer;
*double_ptr = 5;
cout<<an_int<<endl;

The output will remains same that is 0.

So what role type-safety play's here ? and what exactly Bjarne Stroustrup's explained about type-safety ?

Upvotes: 0

Views: 576

Answers (3)

Ingo Blackman
Ingo Blackman

Reputation: 990

I cannot resist. "Type Safety" is a C++ marketing gag. Consider the following code:

#include <stdio.h>

class A {
public:
    int x;
};

class B : public A {
  // B is derived from A, which makes
  // B "compatible" to A
public:
  // B adds a 2nd member, which means
  // that B is "bigger" than A
    int y;
};

int main()
{
    B a1[10];
    A *a2;
    a2 = a1; // this is legal :-( 
    a1[0].x=1;
    a1[0].y=1;
    a2[0].x=2;
    a2[1].x=3; // Upps: this probably overwrites a1[0].y
    printf("a1[0].x = %d\n",a1[0].x);
    printf("a1[0].y = %d\n",a1[0].y);
    return 0;
}

Compile this with "g++ -Wall -pedantic -fstrict-aliasing" or whatever other options you find. I at least have not managed to produce a warning. The code above does not use any type casts and still you get code which breaks or at least quite certainly does not do what you think it should do.

A C++ guru might now recommend to use "vector" or whatever else. But that's not the point. The point is C++ is not type safe at all.

EDIT: Since this seems to be confusing, here is an explanation of what the source of the problem is.

Because C++ is object oriented "class B" is compatible to "class A" (because "class B" is derived from "class A"). So that means you might use a "class B" object at a place where a "class A" object is required. This in turn means you might use a "class B *" pointer at a place where a "class A *" pointer is required.

Now the problem is that C++ allows pointer arithmetic (because of it's C legacy). Pointer arithmetic interacts rather badly with inheritance and compatible types. Because in the example above "a2+1" (a2 is a "class A *" pointer) results in a different address than "a1+1" (a1 is a "class B *" pointer).

So to summarize: C++ deems type "class B *" to be compatible to type "class A *" but unfortunately these types are not compatible when you use them for pointer arithmetic.

Upvotes: -1

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

'Type-Safety' means the compiler won't let you use non matching types for operations, unless you're explicitly asking to do so (e.g. doing a c-style, or c++ reinterpret_cast<> type cast, as you're doing in your sample).

Upvotes: 4

Paul Evans
Paul Evans

Reputation: 27577

Strong static type-safety is a core element of C++. It basically means that you can only transfer information between compatible types, and the most compatible type of any type is that very type. This idea is fortified with ways of using base types with derived type of the same class hierarchy and so on and so forth to great complexity and logical-strength. There is also a core idea that C++ remains as compatible to C as possible. One fall out of this is that void * is compatible with any pointer type. It's usually best avoided, though, as there's always a better design in C++.

Upvotes: 0

Related Questions