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

GCC -Wuseless-cast warnings #1777

Closed
tambry opened this issue Oct 7, 2019 · 10 comments · Fixed by #2902
Closed

GCC -Wuseless-cast warnings #1777

tambry opened this issue Oct 7, 2019 · 10 comments · Fixed by #2902
Assignees
Labels
kind: bug release item: 🔨 further change solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@tambry
Copy link

tambry commented Oct 7, 2019

Using the GCC -Wuseless-cast results in the following warnings:

_deps/json-src/single_include/nlohmann/json.hpp: In member function ‘bool nlohmann::detail::binary_reader<BasicJsonType, SAX>::parse_cbor_internal(bool)’:
_deps/json-src/single_include/nlohmann/json.hpp:4058:109: warning: useless cast to type ‘std::size_t’ {aka ‘long unsigned int’} [-Wuseless-cast]
 4058 |                 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
      |                                                                                                             ^
_deps/json-src/single_include/nlohmann/json.hpp:4112:110: warning: useless cast to type ‘std::size_t’ {aka ‘long unsigned int’} [-Wuseless-cast]
 4112 |                 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
      |                                                                                                              ^
@t-b
Copy link
Contributor

t-b commented Oct 7, 2019

That is actually a bug hiding here:

e.g.

            case 0xBB: // map (eight-byte uint64_t for n follow)
            {
                std::uint64_t len;
                return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
            }

that only works if you can fit a 64bit unsigned integer into a size_t.

@nlohmann
Copy link
Owner

Any idea how to proceed on this?

@tambry
Copy link
Author

tambry commented Oct 24, 2019

@nlohmann Change get_cbor_array() and get_cbor_object() to take std::uint64_t. This will prevent an overflow for the 0x9B and 0xBB cases on platforms where sizeof(std::size_t)==sizeof(std::uint32_t). Then you can remove the superfluous casts.

@jaredgrubb
Copy link
Contributor

I dont think there's a bug. The scenario would be that there's a platform that wants to read CBOR that has more than 4 billion things on a platform that has memory buffers that literally cannot hold 4 billion things. That won't work.

I think maybe GCC is being too aggressive here. unsigned long and uint64_t are always distinct types. These types of warnings are meant to flag suspicious or dubious things, and casting between two types of the same size (on the platform reporting this issue) does not feel like a dubious thing to do.

I'm tempted to say this is Behaving Correctly. What do you all think? (A patch could be to pragma-ignore this warning in our header for GCC if we want to be warnings-clean for our users).

@tambry
Copy link
Author

tambry commented Oct 24, 2019

The scenario would be that there's a platform that wants to read CBOR that has more than 4 billion things on a platform that has memory buffers that literally cannot hold 4 billion things. That won't work.

Technically possible on x86 with PAE.

That said, couldn't the number of elements be small enough (e.g. 163) despite it being a 64-bit length?

unsigned long and std::uint64_t are always distinct types

Certainly not. std::uint64_t is simply an alias to a type whose size is at least 64-bit. This may well be unsigned long depending on your platform.

I would be OK with simply being clean for this warning though.

@jaredgrubb
Copy link
Contributor

This is a language concept not a platform concept. size_t is defined to be the type that can hold the biggest size (sizeof(a)) or, as a corollary, an index into an array (or buffer). So if size_t is 32-bit, then you literally cannot have buffers that are bigger than 4GB. (This is subtly different from what you're describing is where you can have 32-bit pointers on a machine with 8GB of total physical memory, where the virtual memory subsystem makes it all work out.)

You're right about the uint64_t and size_t; I thought C++ required these to be different (and have different mangling like 'long' has) but you're right.

Still I don't really think there is something to fix here?

@t-b
Copy link
Contributor

t-b commented Oct 24, 2019

Well we could throw an exception if we try to read an array/object with uint64 size and have only a std::size_t < 64.

@stale
Copy link

stale bot commented Nov 23, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Nov 23, 2019
@stale stale bot closed this as completed Dec 1, 2019
@nlohmann nlohmann reopened this Dec 10, 2019
@stale stale bot removed the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Dec 10, 2019
@stale
Copy link

stale bot commented Jan 9, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Jan 9, 2020
@stale stale bot closed this as completed Jan 16, 2020
@nlohmann
Copy link
Owner

Fixed with #2902.

@nlohmann nlohmann added release item: 🔨 further change solution: proposed fix a fix for the issue has been proposed and waits for confirmation and removed state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated labels Jul 31, 2021
@nlohmann nlohmann self-assigned this Jul 31, 2021
@nlohmann nlohmann added this to the Release 3.9.2 milestone Jul 31, 2021
@nlohmann nlohmann linked a pull request Jul 31, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug release item: 🔨 further change solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants