Code considered only at compile time can contain Undefined Behaviour?

Asked

Viewed 91 times

6

When designing a function that adds up two values of any distinct classes, I can write the following in a generic way:

template <typename T, typename U>
decltype((*(T*)0) + (*(U*)0)) add(T t, U u) {
    return t + u;
}

The interesting part is the kind of return: decltype((*(T*)0) + (*(U*)0)). In other words: "The type resulting from the sum of an object of type T with a guy U".

But to get an object like T, use (*(T*)0) which, although invalid if executed, always results in the type T. Another way to achieve the same result would be like this: T() + U(). The problem is that so it is assumed that there is a standard constructor for the types, even if I don’t even need a constructor for the function.

My question is: writing this function is actually allowed and does not create Undefined Behaviour?

More generally, I can use expressions that result in Undefined Behaviour when executed, but that have a well-defined type, within a decltype?


Note: In C++11 it is possible to write:

template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
    return t + u;
}

And in C++14 it is possible to write:

template <typename T, typename U>
auto add(T t, U u) {
    return t + u;
}

But that’s not relevant to the question.

  • Excellent question. I would guess that I would not create an indefinite behavior but I would not know how to substantiate, I just know that if the code can be properly generated and not be undefined, what’s the problem? In fact I’m going to research this. But something tells me that you are the one who can give the best answer here :)

1 answer

1

You can use any valid expression within the decltype. And it does not matter if the instruction was executed its behavior would be undefined. This is because decltype does not execute the expression and then uses the resulting type. Instead it infers the resulting type from the expression.

In the case of your example, he doesn’t melt the null pointer to find the type. He knows that the slippage of a T pointer is a value of type T.

Besides, there is no way the expression can be executed, since, as you said yourself, this is all done at compilation time.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.