Strong Typing |
Written by Nikos Vaggalis | |||||||
Thursday, 18 November 2010 | |||||||
Page 5 of 6
Implicit conversionExample 21 #include <stdio.h> a=65535; //dereferenced value is : 255 Here the void pointer was implicitly (without using the cast operator) converted into an unsigned char pointer, thus when dereferencing, the contents of the address will be interpreted as unsigned char's not unsigned short's, which will result in a 1 byte shift (>>8) operation which will again result into data loss. C acts as weakly typed language in this case; it allows converting from a void pointer to any other pointer type even if the actual type of the value has no relation to the type being converted to. Also when assigning to or from a void pointer there is an implicit cast happening. However, when the pointer is typed (carries type information) then we get a compiler warning: Example 22#include <stdio.h> int main() a=65535; printf("dereferenced value is %d\n", *c); warning: assignment from incompatible pointer type A much simpler example can be constructed without using void pointers and statically typing the pointer: Example 23#include <stdio.h> int main() char *p; a=82; warning: assignment from incompatible pointer type Not having type information can result into erroneous operations and conversions that would be avoided if type checking were enforced. Perl types its pointersAt the same time Perl, which is considered weakly typed, enforces type safety and type checking on references and disallows implicit conversions between them (and as a matter of fact it even disallows explicit conversions since there is no cast operator in Perl). So it is acting as a strongly typed language. When you take a reference to, for example an array, then you cannot treat this reference as it is pointing to a hash: @array=(1,2,3); This results in a runtime exception print %$ref; This results in a runtime exception print @$ref; OK,at last! or $myref=\%a; #pointer to a hash Not an ARRAY reference at 3.pl line 2. In the examples above I tried, as in a void pointer, to interpret the contents of the address pointed at by the reference as another type, but I can't, since the referent is typed. As a matter of fact, Perl although being untyped, always knows the type of its pointers and one can get to that information by using the ref keyword: @a=(1,2,3); Perl knows for sure that we point to an ARRAY and to use it correctly we have to use the correct notation; so to dereference an array reference we must prepend the reference with @; print $@myref;#123 Contrast this with the C void pointer examples. As demonstrated, Perl uses type safe pointers. However when it comes to function pointers, Perl does guarantee type safety at a fundamental level (it is a pointer to a function and this cannot be changed), but cannot enforce either return result type safety or parameter type safety since the parameters are optional and "untyped". Recall that a scalar variable parameter can hold any scalar value; a reference to a built in type, a reference to an instance, a number (not specifically a int,short,ushort,char etc) a string, a boolean or precisely in Perl terms an integer ("IV"),a double ("NV"), a string ("PV" for pointer value), a reference ("RV"), and a special object ("magical"). At the same time C# does exactly employ that model of type safety when using function pointers or so called delegates. The signature and the return result of the method must be an exact match of that of the delegate. However delegates make implicit conversions of their return value type and their parameter(s) type because they support the concept of covariance and contravariance. It could be suggested that you should use Perl function prototypes for providing something similar but it is not foolproof and not recommended. Type safety is important but it is not always desired. Sometimes you have to trade safety for flexibility; that is why a late bound delegate invocation also exists (dynamicinvoke) and why the new C# dynamic type was introduced and why the void pointer exists. <ASIN:0470532874> <ASIN:0735627045> <ASIN:0735619573> <ASIN:0672328917> |
|||||||
Last Updated ( Friday, 09 November 2012 ) |