Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ssize has not been declared in std #246

Closed
ned14 opened this issue Apr 20, 2020 · 10 comments · Fixed by #247
Closed

ssize has not been declared in std #246

ned14 opened this issue Apr 20, 2020 · 10 comments · Fixed by #247

Comments

@ned14
Copy link
Contributor

ned14 commented Apr 20, 2020

quickcpplib/include/quickcpplib/gsl-lite/include/gsl/gsl-lite.hpp:984:12: error: ‘ssize’ has not been declared in ‘std’
  984 | using std::ssize;
      |            ^~~~~

Cause:

#define gsl_HAVE_STD_SSIZE              ( gsl_COMPILER_GNUC_VERSION >= 1000 )

However ssize() is a C++ 20 only feature, not a GCC 10 feature. So this is the wrong check to do.

@mbeutel
Copy link
Collaborator

mbeutel commented Apr 21, 2020

Thank you. std::ssize() support was added to libstdc++ only for GCC 10, so the version check is necessary, but we additionally need to check the language version, i.e. #if __cplusplus > 201703L. (GCC sets __cplusplus=201709L for tentative C++20 support.)

std::ssize() has since appeared in libc++ and in the MSVC STL as well, so this check will need an update anyway.

Edit: There is the __cpp_lib_ssize feature test macro but libstdc++ GCC 10 doesn't define it yet: https://gcc.godbolt.org/z/_JSaYy

@ned14
Copy link
Contributor Author

ned14 commented Apr 21, 2020

Me personally, I would write a local ssize() implementation which prefers a std::ssize(), uses that if available, otherwise falls back to an emulation. You can see an example of such a technique for std::launder() at:

https://github.com/ned14/quickcpplib/blob/master/include/quickcpplib/start_lifetime_as.hpp#L33

@mbeutel
Copy link
Collaborator

mbeutel commented Apr 21, 2020

That technique is prone to ADL hijacking:

struct Evil : std::array<int, 1>{ };
constexpr int ssize(Evil) { return 2; }
static_assert(gsl::ssize(Evil{ }) == 1);

Also, unlike std::launder() which requires compiler magic, gsl::ssize() has a straightforward portable implementation; what would be the benefit of conditionally delegating to std::ssize()?

@ned14
Copy link
Contributor Author

ned14 commented Apr 21, 2020

I don't think that technique is prone to ADL hijacking. For something like:

namespace std_or_emulation
{
  using namespace std;
  template <class C>
  constexpr auto ssize(const C& c, ...)  // inferior overload 
    -> std::common_type_t<std::ptrdiff_t,
                          std::make_signed_t<decltype(c.size())>> 
  {
      using R = std::common_type_t<std::ptrdiff_t,
                                   std::make_signed_t<decltype(c.size())>>;
      return static_cast<R>(c.size());
  }
}
template<class T> constexpr auto ssize(const T&v) { return std_or_emulation::ssize(v); }

Here it would select the best available overload in namespace std_or_emulation. You deliberately make your emulation an inferior overload choice valid if and only if namespace std doesn't provide a better one.

ADL never comes into play here, because all lookup is namespace-qualified.

@mbeutel
Copy link
Collaborator

mbeutel commented Apr 21, 2020

Right. But please note that the example you referenced is prone to hijacking because you don't use a qualified name there.

Nevertheless, what is the benefit of delegating to std::ssize()?

@ned14
Copy link
Contributor Author

ned14 commented Apr 21, 2020

Nevertheless, what is the benefit of delegating to std::ssize()?

To get early notification of when your standard library implementator has done something weird, mainly. Otherwise, none.

mbeutel added a commit to mbeutel/gsl-lite that referenced this issue May 13, 2020
@dskachan
Copy link

Hello everyone.
I have setup:
Ubuntu 20.04, gcc 10.2.0; cmake 3.18.0; conan 1.27.1. what else... ccache 3.7.7

I have a project, which uses -std=gnu++17 flag. so, 17th standard. someday we will move to 2a, but now not about it.
The project uses gsl-lite/0.36.0 over conan.

upon compilation, I'm getting mentioned above error:

/root/.conan/data/gsl-lite/0.36.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/gsl/gsl-lite.hpp:974:12: error: ‘ssize’ has not been declared in ‘std’
  974 | using std::ssize;

@mbeutel mentioned that std::ssize_t is for gcc 10+; and standard 2a+. so, it should not include std::ssize_t, right?
what am I doing wrong?

cmake generated me such a line:

ccache /usr/local/bin/c++ -DGSL_THROW_ON_CONTRACT_VIOLATION -D_GLIBCXX_USE_CXX11_ABI=1  -isystem /root/.conan/data/gsl-lite/0.36.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include ####### MANY OTHER INCLUDES ##### -fdiagnostics-color=always -g -fPIC -Wall -Wextra -Wshadow -Winit-self -Wfloat-equal -Wtrigraphs -Wconversion -Wcast-align -Wlogical-op -Wunsafe-loop-optimizations -Wno-unused-parameter -Wdouble-promotion -Wpointer-arith -Wformat=2 -pthread -std=gnu++17 -MD -MT src/CMakeFiles/project.dir/Progress.cpp.o -MF src/CMakeFiles/project.dir/Progress.cpp.o.d -o src/CMakeFiles/project.dir/project.cpp.o -c ../src/Progress.cpp

@mbeutel
Copy link
Collaborator

mbeutel commented Jul 27, 2020

The project uses gsl-lite/0.36.0 over conan.
[...]
what am I doing wrong?

The fix for this issue was committed in 913e86d which found its way into version 0.37, released May 13, 2020.

The latest version of gsl-lite in Conan Center seems to be 0.36.0. I guess one could open an issue in their repo to have the package updated.

@dskachan
Copy link

Sorry for off-topic
is tag 0.37.0 intentionally without "v" in the name?

@mbeutel
Copy link
Collaborator

mbeutel commented Jul 28, 2020

is tag 0.37.0 intentionally without "v" in the name?

No, that was unintentional. Thanks for bringing this up; I just pushed an additional "v0.37.0" tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants