Skip to content
This repository has been archived by the owner. It is now read-only.

std::tuple_size should be a struct #39871

Closed
llvmbot opened this issue Dec 3, 2018 · 7 comments
Closed

std::tuple_size should be a struct #39871

llvmbot opened this issue Dec 3, 2018 · 7 comments
Assignees

Comments

@llvmbot
Copy link
Collaborator

@llvmbot llvmbot commented Dec 3, 2018

Bugzilla Link 39871
Resolution FIXED
Resolved on Jan 11, 2019 15:19
Version unspecified
OS All
Reporter LLVM Bugzilla Contributor
CC @mclow,@zygoloid

Extended Description

Currently std::tuple_size is declared as class tuple_size. According to the C++ standard, tuple_size is a struct (http://eel.is/c++draft/tuple.helper#lib:tuple_size).

This creates portability problems between libcxx and libstdc++, which correctly declares it as a struct. Currently using either will result in -Wmismatched-tags.

@llvmbot
Copy link
Collaborator Author

@llvmbot llvmbot commented Dec 3, 2018

assigned to @mclow

Loading

@llvmbot
Copy link
Collaborator Author

@llvmbot llvmbot commented Dec 3, 2018

Further research revealed this might've changed recently? The C++14 draft I have access to (N3936, Page 491) lists them as class , same as the C++11 draft (N3337, Page 473).

Since the only ABI difference will be on MSVC, and MSVC is using struct, I think it could be possible to change it to a struct. Which will possibly break programs compiled against an old version of libcxx on Windows, but will provide ABI compatibility with MSVC in the future.

Loading

@mclow
Copy link

@mclow mclow commented Dec 3, 2018

[ Short answer, it's not libc++, it's the standard ]

In [utility.syn], we've got (this is all post-2017):

// 19.4.4, tuple-like access to pair
template class tuple_size;
template<size_t I, class T> class tuple_element;
template<class T1, class T2> struct tuple_size<pair<T1, T2>>;
template<size_t I, class T1, class T2> struct tuple_element<I, pair<T1, T2>>;

In [pair.astuple]:
template<class T1, class T2>
struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> {};

In [tuple.syn]
// 19.5.3.6, tuple helper classes
template class tuple_size;
template class tuple_size;
template class tuple_size;
template class tuple_size;

template<class... Types> class tuple_size<tuple<Types...>>;

and in [tuple.helper]:

template struct tuple_size;
template<class... Types>
class tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> {};

In [array.syn]:
template class tuple_size;
template<size_t I, class T> class tuple_element;

template<class T, size_t N>
struct tuple_size<array<T, N>>;
template<size_t I, class T, size_t N>
struct tuple_element<I, array<T, N>>;

in [array.tuple]:
template<class T, size_t N>
struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };
tuple_element<I, array<T, N>>::type;

I'll have to clean this up in the standard.

Loading

@llvmbot
Copy link
Collaborator Author

@llvmbot llvmbot commented Dec 7, 2018

Ouch, alright, that's unfortunate.
Is libcxx actually defining std::tuple_size differently, in different places?

Loading

@mclow
Copy link

@mclow mclow commented Dec 7, 2018

It appears that libc++ is consistent; it uses 'class' everywhere.

Loading

@mclow
Copy link

@mclow mclow commented Jan 11, 2019

The standard isn't going to change; see cplusplus/draft#534

Committed revision 350972 to make tuple_size a struct everywhere.

Loading

@zygoloid
Copy link
Mannequin

@zygoloid zygoloid mannequin commented Jan 11, 2019

As of r348233, Clang ignores declarations in system headers when deciding whether to issue -Wmismatched-tags, which should cover this more generally (but only for new versions of Clang, of course).

Loading

This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants