3 ms·
> if you supply a buffer that actually contains a float, or a string with numbers in it, it will convert it for you on the fly as well, or return 0 if it can't
by 8organicbits 6y ago
> if you supply a buffer that actually contains a float, or a string with numbers in it, it will convert it for you on the fly as well, or return 0 if it can't. If instead you actually want to know what is inside the buffer before you access it, you can call root.GetType() or root.IsInt() etc.
I've started to prefer functions that are explicit about their error cases and have interfaces that make it obvious about what errors you'd want to handle. Unexpectedly getting a zero when you get garbage data may cause issues.
Thinking about it, zero is often used as a success code: ERROR_SUCCESS is 0x0 on Windows. So garbage in, ERROR_SUCCESS out??
Something like:
value, err = root.AsInt64();
makes it clear you have an error path. You can still ignore `err`, like when you are moving fast and breaking things or it's somehow certain to always succeed, but it's clear that there's an unhandled error path.
- typon 6y agoIf you use cpp17, you can use the built-in std::optional to solve this problem.
- taeric 6y agoStrictly, not the same. One returns a value and an error. One returns a value or nothing. Having the error can signal both if a value could not be retrieved, or if it could be retrieved, but was coerced, as an example.
- iso8859-1 6y agoBut look at the encoding, they compact the int down to the amount of bytes it needs for storage. There is no space to encode the type, and there is no way to distinguish encoded uint from an int. You must layer your own schema on top.
- 8organicbits 6y agoI believe this is the docs that explain their type byte. That information is stored: https://google.github.io/flatbuffers/flatbuffers_internals.html https://google.github.io/flatbuffers/flatbuffers_internals.h... > A type byte is made up of 2 components (see flexbuffers.h for exact values): > * 2 lower bits representing the bit-width of the child (8, 16, 32, 64). This is only used if the child is accessed over an offset, such as a child vector. It is ignored for inline types. > * 6 bits representing the actual type (see flexbuffers.h). > Thus, in this example 4 means 8 bit child (value 0, unused, since the value is in-line), type SL_INT (value 1). Type aware methods like `.isInt()` wouldn't make sense if they couldn't determine the underlying type.
- Aardappel 6y agoAs you can see from the documentation, `AsInt64` is a convenience method that either says, I know this is an int, or make it so. There are also ways to check the type before you access, if you prefer. You can even check if its unsigned, if you want that level of type-safety.
- bowmessage 6y agoRight, but GP is suggesting that the requirement to ignore an 'err' value that would make the API user think twice about possible failure cases that could otherwise go ignored with the convenience API.
- Aardappel 6y agoYou are choosing to use a schema-less, dynamically typed representation (where a strongly typed alternative is directly available). I'd say, the convenience of being able to just say I am going to assume this is an int is fitting. If you wanted to be forced to error check (which needs an if-then in most languages), you might as well use the schema based, strongly typed version of the system instead, which would guarantee correct types for you, and requires no error checking.