Function type checking

Hello,

In an attempt to revise C++ programming I have found something that is concerning me. Please consider this small example program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;

int add(short x, short y);

int main(){

	double a = 5.5;
	double b = 10.15;

	add(a,b);

}

int add(short x, short y){

	return x+y;
}


The above program compiles perfectly in GCC(G++)

Because a double is a totally different type to a short I would have thought that the compiler should generate a compile time error. Maybe it's just me, but I see this as a potential route to difficult to fix bugs.

Would somebody please explain why this program compiles? Are there any switches on GCC which will turn on additional type checking?

Many Thanks
N
Most intrinsic (built in) data types can be implicitly cast (what your doing above) to one another.
I don't know about GCC flags so I'll let someone else have a crack at that, but you would need something to turn off implicit casting. One solultion would be to declare the function as explicit.
I.e: explicit int add(short x, short y);
Not an expert on GCC by any stretch, but have you tried the -Wall or -Wextra flags?

Not sure if they'll work but worth a shot. I know some compilers are happy to let quiet conversions such as this go by.
Maybe it's just me, but I see this as a potential route to difficult to fix bugs.

It isn't. If you're trying to pass a fraction to a function that only accepts integers and it is actually crucial for the logic of your program that the number is not truncated, then you generally have a conceptual error and likely misunderstood the purpose of the function. And since people usually do not call functions they don't know anything about, it's not a problem.

To take your example with add, it's just either badly named (should be add_short or similar) or badly designed (should be a template).

I can't remember ever encountering a bug in my own software that was caused by unwanted truncation, nor can I remember any post in this or any other C++ forum where someone had a problem due to accidental truncation of a floating point number.
Last edited on
@Mathhead200: explicit can only be applied to constructors. Even if it were a constructor, it only takes effect on constructors with a single parameter.

There's no way to stop implicit type-casting, unless the compiler has a flag that disables such behaviour. You could create your own wrapper for each basic type, but that would take a bit of time. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class UnsignedInt
{
    public:
        UnsignedInt();
        explicit UnsignedInt(const unsigned int &Value);
        explicit UnsignedInt(const UnsignedInt &Value);

    private:
        unsigned int Value_;

    public:
        UnsignedInt &operator = (const UnsignedInt &Value);
};

UnsignedInt::UnsignedInt() : Value_(0U){ }
UnsignedInt::UnsignedInt(const unsigned int &Value) : Value_(Value) { }
UnsignedInt::UnsignedInt(const UnsignedInt &Value) : Value_(Value.Value_) { }

UnsignedInt &UnsignedInt::operator = (const UnsignedInt &Value)
{
    this->Value_ = Value.Value_;
    return(*this);
}


Wazzak
Last edited on
Thank you to everyone thus far.

I think what was confusing me is that the following JAVA equivalent code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

public class typecheck {

        public static void main(String[] args){

                typecheck tc = new typecheck();

                double a = 5;
                double b = 1;

                tc.add(a,b);

        }

        int add(int x, int y){

                return x+y;
        }
}


When compiled generates a type error as I would expect. Does this mean that Java is more strongly typed than C++?

Does this mean that Java is more strongly typed than C++?

Yes, it does.
Here is some fun
http://www.ima.umn.edu/~arnold/disasters/ariane.html

This software was written in Ada which is type fanatic. So for sure the engineers would have had to put in specific type casting. The problem was that the value was just too large and Ada threw an exception.

Ironically, the system involved in this error was not actually needed during flight, it was used to set up the rocket on the launch pad and was kept running 'just in case'. The uncaught exception brought the whole system down.

The automatic conversion of inbuilt types in C++ is a quirk, inherited from C but does not usually cause problems since all C++ programmers are aware of this quirk.

Java also has quirks in this area, notably inbuilt types have value semantics whereas user defined types have reference semantics. I believe the in built types are not derived from Object? and so you have to use wrapped versions if you want to store them in containers?

> I would have thought that the compiler should generate a compile time error. Maybe it's just
> me, but I see this as a potential route to difficult to fix bugs.

1
2
3
4
5
6
7
8
9
10
11
12
int add(short x, short y);

int main(){

	double a = 5.5;
	double b = 10.15;
    
    // C++11: placing braces around an expression {expression} 
    // inhibits narrowing conversions of the expression
	add( {a}, {b} ) ; // error: narrowing conversion of a from 'double' to 'short'
    // error: narrowing conversion of b from 'double' to 'short'
}



Thanks to everyone for such informative replies.

Conducting further tests I have found that the following code fails to compile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

int add(short x, short y);
int add(int x, int y);

int main(){

        double a = 5.1;
        double b = 10.15;

        add(a,b);

}

int add(short x, short y){

        return x+y;

}

int add(int x, int y){

       return x+y;

}


All makes sense now :) Thank you all :)
Topic archived. No new replies allowed.