Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is this code legal or not? Mr Flibble Is Very Cross

41 views
Skip to first unread message

Mr Flibble

unread,
Apr 12, 2020, 12:17:31 AM4/12/20
to
Hi!

Flibble is currently very cross due to the following code:

#include <cstdint>
#include <type_traits>
#include <variant>
#include <iostream>

template <typename T>
T foo(const std::variant<int64_t, double, std::string>& v)
{
T result;
std::visit([&result](auto&& a)
{
typedef std::decay_t<decltype(a)> vt;
if constexpr (std::is_same_v<vt, double>)
result = static_cast<T>(a);
else if constexpr (std::is_same_v<vt, int64_t>)
result = static_cast<T>(a);
else if constexpr (std::is_same_v<vt, std::string> && std::is_class_v<T>)
result = T::from_string(a); // Pfft
else
throw std::logic_error("wibble");
}, v);
return result;
}

int main()
{
std::cout << foo<double>(int64_t{});
}

Is the line marked "Pfft" legal or not? g++ (Wandbox HEAD) thinks it is whilst clang++ (Wandbox HEAD) thinks it is illegal. I would expect the constexpr if statement to not be considered if T isn't of class type.

https://wandbox.org/permlink/IcnMGxGSdAkBb2iP

/Flibble

--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin

“You won’t burn in hell. But be nice anyway.” – Ricky Gervais

“I see Atheists are fighting and killing each other again, over who doesn’t believe in any God the most. Oh, no..wait.. that never happens.” – Ricky Gervais

"Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say."

Alf P. Steinbach

unread,
Apr 12, 2020, 11:30:49 AM4/12/20
to
I agree with your reasoning. It's syntactically valid so should be OK
when that branch isn't taken.

Since partial specialization of functions isn't supported one workaround
is to define a class template with a static function, specialize it for
each case, and invoke the static function from a free function template.

In passing, why throw a `std::logic_error`? If the logic is astray, then
best to terminate?

- Alf

Mr Flibble

unread,
Apr 12, 2020, 11:42:53 AM4/12/20
to
Rather than a workaround I am going to raise a clang++ defect report and leave it as-is because that method is the cleanest in my opinion (the whole point of if constexpr is so you don't have to specialize templates).

>
> In passing, why throw a `std::logic_error`? If the logic is astray, then best to terminate?

I only catch std::logic_error exceptions to log and then re-throw so the program will terminate.

Mr Flibble

unread,
Apr 12, 2020, 4:06:20 PM4/12/20
to
On 12/04/2020 16:30, Alf P. Steinbach wrote:
I have raised a clang++ defect report:

https://bugs.llvm.org/show_bug.cgi?id=45506

Paavo Helde

unread,
Apr 13, 2020, 2:04:18 AM4/13/20
to
12.04.2020 18:30 Alf P. Steinbach kirjutas:
> In passing, why throw a `std::logic_error`? If the logic is astray, then
> best to terminate?

This is a more general issue. Most of C++ code resides in various
libraries or may eventually end up in various libraries, and a library
should not decide whether it is appropriate to kill the whole process or
not. This is a task for the main client application.

Consider e.g. Python which can be used in interactive regime. You don't
want to kill the whole Python process in some low-level C++
implementation code just because the user mixed up some parameters in
the Python interactive command line.

Ned Latham

unread,
Apr 13, 2020, 2:21:51 AM4/13/20
to
Paavo Helde wrote:
> Alf P. Steinbach kirjutas:
> >
> > In passing, why throw a `std::logic_error`? If the logic is astray,
> > then best to terminate?
>
> This is a more general issue. Most of C++ code resides in various
> libraries or may eventually end up in various libraries, and a library
> should not decide whether it is appropriate to kill the whole process
> or not. This is a task for the main client application.

Well said, that man!

The widespread ignorance of that principle is amazing.

Öö Tiib

unread,
Apr 13, 2020, 2:48:00 AM4/13/20
to
On current case the else was when std::variant<int64_t, double, std::string>
contained somehow something else but int64_t, double or std::string.
It is not even logic error but case where std::variant somehow managed
to violate its specifications. I would perhaps also abort, that can't
be something that is fixed by catcher.

0 new messages