Invalid assignment to unsigned char C++ - c++

I wrote the following but for some reason calling InstructionVal(b) is invalid.
intellisense is spitting out:
Only () is allowed for initializer member NPPInstructionDef::InstructionVal
here is the offending code:
//Single Instruction Definition for Instruction Dictionary
typedef struct NPPInstructionDef
{
const char* InstructionName;
const unsigned char* InstructionVal[];
NPPInstructionDef(const char* a, const unsigned char* b[]): InstructionName(a), InstructionVal()
{
}
}NPPInstruction;
Any Ideas? Thanks.

First, I'm assuming your initialization is InstructionVal(
b ), rather than the InstructionVal() which you've written.
But even then, what you've written shouldn't compile.
This is the usual problem, due to the fact that C style arrays
are broken, and shouldn't be used. Your definition:
unsigned char const* InstructionVal[];
defines an array of unknown length (thus, illegal in a class
defintion) of unsigned char*. There's no way to initialize
this in an initialization list, except by () (value
initialization).
What you want is:
std::vector <unsigned char*> InstructionVal;
, and the constructor should be:
NPPInstructionDef( std::string const& a,
std::vector <unsigned char> const& b );
, or perhaps more likely:
template <typedef Iterator>
NPPInstructionDef( std::string const& a,
Iterator begin,
Iterator end )
: InstructionName( a )
, InstructionDef( begin, end )
{
}
(This supposes, of course, that InstructionName is
std::string, instead of char const*. Which will avoid any
issues of lifetime of the string, for example, and allow easy comparison, etc.)

Related

Template overloads with array types: Force char array to use string_view

I have a print() template method overloaded to handle different types. There are three categories I'm concerned with:
Array types of scalar values excluding literal strings (e.g. unsigned foo[5])
String literals (e.g. "Hello World")
String types (char const* and std::string)
The first item should be handled differently than strings (the last 2 points). Here is some code I've written to try to distinguish between them (LIVE SAMPLE):
template<typename Container, typename T,
std::enable_if_t<std::is_pod_v<T> && !std::is_pointer_v<T> && !std::is_array_v<T>, int> = 0>
void print(T const&)
{
std::cout << "Generic Value\n";
}
template<typename Container, typename Array, std::size_t Size>
void print(Array const (&)[Size])
{
std::cout << "Array\n";
}
template<typename Container>
void print(std::string_view)
{
std::cout << "String View\n";
}
int main()
{
{ // GOOD: Uses string_view
char const* value = "Hello";
print<int>(value);
}
{ // GOOD: Uses string_view
std::string value = "value";
print<int>(value);
}
{ // GOOD: Uses array overload
unsigned value[] = {1, 2, 3};
print<int>(value);
}
{ // BAD: Should use the string_view overload
print<int>("Hello");
}
}
The output I get:
String View
String View
Array
Array
Note the case labeled BAD. I expect this to be handled by string_view, but because it's technically an array, it doesn't. I suppose I could solve this by doing an enable_if with is_same to check for (and exclude) char types for the Array parameter, but that seems a bit hairy.
Is there a more manageable way to generically program for these types? Essentially I want to handle strings as strings (mostly because of the null terminator), and non-strings as raw bytes of data.
Some context / notes:
The example uses a Container template argument that is pointless. This is just to force all the functions to be templates. In my real code this is a meaningful template argument (actually refers to a STL container that the value passed gets written into as a series of bytes). Also the print method in my real code is actually an overloaded << operator. The whole point of my real code is to write various types as binary data to a container (like iostreams for binary data). I handle certain types in special ways (e.g. strings ignore null terminators), which is why I've got so many overloads.
The array template is a better match for char[] types, since the string_view version involves a user-defined conversion.
You can either disable the array version for char[] types with SFINAE:
template<typename Container, typename Array, std::size_t Size,
std::enable_if_t<!std::is_same_v<Array, char>, int> = 0>
void print(Array const (&)[Size])
{
std::cout << "Array\n";
}
Or implement an additional proxy overload:
template<typename Container, std::size_t Size>
void print(char const (&s)[Size])
{
print<Container>(std::string_view(s));
}
Since a string literal is an lvalue const char[N], there is no way for it to pick std::string_view over Array const(&)[Size]. You would have to disable the array overload for char:
template<typename Container, typename Array, std::size_t Size>
std::enable_if_t<!std::is_same_v<Array, char>> print(Array const (&)[Size])
But this probably isn't the best solution, as you can't know if it is null terminated (There is no way to tell if a const char array is a string literal or an array of bytes). e.g., the following is UB:
char value[] = { 1 }; // Not null terminated
print<int>(value); // Constructing a string_view from non-null terminated array
You would probably want a string view literal, so you won't need to worry about the array overload being used:
using namespace std::literals;
print<int>("Hello"sv);

Detecting string literals at compile time [duplicate]

I have a class to wrap string literals and calculate the size at compile time.
The constructor looks like this:
template< std::size_t N >
Literal( const char (&literal)[N] );
// used like this
Literal greet( "Hello World!" );
printf( "%s, length: %d", greet.c_str(), greet.size() );
There is problem with the code however. The following code compiles and I would like to make it an error.
char broke[] = { 'a', 'b', 'c' };
Literal l( broke );
Is there a way to restrict the constructor so that it only accepts c string literals? Compile time detection is preferred, but runtime is acceptable if there is no better way.
There is a way to force a string literal argument: make a user defined literal operator. You can make the operator constexpr to get the size at compile time:
constexpr Literal operator "" _suffix(char const* str, size_t len) {
return Literal(chars, len);
}
I don't know of any compiler that implements this feature at this time.
Yes. You can generate compile time error with following preprocessor:
#define IS_STRING_LITERAL(X) "" X ""
If you try to pass anything other than a string literal, the compilation will fail. Usage:
Literal greet(IS_STRING_LITERAL("Hello World!")); // ok
Literal greet(IS_STRING_LITERAL(broke)); // error
With a C++11 compiler with full support for constexpr we can use a constexpr constructor using a constexpr function, which compiles to a non-const expression body in case the trailing zero character precondition is not fulfilled, causing the compilation to fail with an error. The following code expands the code of UncleBens and is inspired by an article of Andrzej's C++ blog:
#include <cstdlib>
class Literal
{
public:
template <std::size_t N> constexpr
Literal(const char (&str)[N])
: mStr(str),
mLength(checkForTrailingZeroAndGetLength(str[N - 1], N))
{
}
template <std::size_t N> Literal(char (&str)[N]) = delete;
private:
const char* mStr;
std::size_t mLength;
struct Not_a_CString_Exception{};
constexpr static
std::size_t checkForTrailingZeroAndGetLength(char ch, std::size_t sz)
{
return (ch) ? throw Not_a_CString_Exception() : (sz - 1);
}
};
constexpr char broke[] = { 'a', 'b', 'c' };
//constexpr Literal lit = (broke); // causes compile time error
constexpr Literal bla = "bla"; // constructed at compile time
I tested this code with gcc 4.8.2. Compilation with MS Visual C++ 2013 CTP failed, as it still does not fully support constexpr (constexpr member functions still not supported).
Probably I should mention, that my first (and preferred) approach was to simply insert
static_assert(str[N - 1] == '\0', "Not a C string.")
in the constructor body. It failed with a compilation error and it seems, that constexpr constructors must have an empty body. I don't know, if this is a C++11 restriction and if it might be relaxed by future standards.
No there is no way to do this. String literals have a particular type and all method overload resolution is done on that type, not that it's a string literal. Any method which accepts a string literal will end up accepting any value which has the same type.
If your function absolutely depends on an item being a string literal to function then you probably need to revisit the function. It's depending on data it can't guarantee.
A string literal does not have a separate type to distinguish it from a const char array.
This, however, will make it slightly harder to accidentally pass (non-const) char arrays.
#include <cstdlib>
struct Literal
{
template< std::size_t N >
Literal( const char (&literal)[N] ){}
template< std::size_t N >
Literal( char (&literal)[N] ) = delete;
};
int main()
{
Literal greet( "Hello World!" );
char a[] = "Hello world";
Literal broke(a); //fails
}
As to runtime checking, the only problem with a non-literal is that it may not be null-terminated? As you know the size of the array, you can loop over it (preferable backwards) to see if there's a \0 in it.
I once came up with a C++98 version that uses an approach similar to the one proposed by #k.st. I'll add this for the sake of completeness to address some of the critique wrt the C++98 macro.
This version tries to enforce good behavior by preventing direct construction via a private ctor and moving the only accessible factory function into a detail namespace which in turn is used by the "offical" creation macro. Not exactly pretty, but a bit more fool proof. This way, users have to at least explicitly use functionality that is obviously marked as internal if they want to misbehave. As always, there is no way to protect against intentional malignity.
class StringLiteral
{
private:
// Direct usage is forbidden. Use STRING_LITERAL() macro instead.
friend StringLiteral detail::CreateStringLiteral(const char* str);
explicit StringLiteral(const char* str) : m_string(str)
{}
public:
operator const char*() const { return m_string; }
private:
const char* m_string;
};
namespace detail {
StringLiteral CreateStringLiteral(const char* str)
{
return StringLiteral(str);
}
} // namespace detail
#define STRING_LITERAL_INTERNAL(a, b) detail::CreateStringLiteral(a##b)
/**
* \brief The only way to create a \ref StringLiteral "StringLiteral" object.
* This will not compile if used with anything that is not a string literal.
*/
#define STRING_LITERAL(str) STRING_LITERAL_INTERNAL(str, "")

Why aren't string literals passed as references to arrays instead of opaque pointers?

In C++, the type of string literals is const char [N], where N, as std::size_t, is the number of characters plus one (the zero-byte terminator). They reside in static storage and are available from program initialization to termination.
Often, functions taking a constant string doesn't need the interface of std::basic_string or would prefer to avoid dynamic allocation; they may just need, for instance, the string itself and its length. std::basic_string, particularly, has to offer a way to be constructed from the language's native string literals. Such functions offer a variant that takes a C-style string:
void function_that_takes_a_constant_string ( const char * /*const*/ s );
// Array-to-pointer decay happens, and takes away the string's length
function_that_takes_a_constant_string( "Hello, World!" );
As explained in this answer, arrays decay to pointers, but their dimensions are taken away. In the case of string literals, this means that their length, which was known at compile-time, is lost and must be recalculated at runtime by iterating through the pointed memory until a zero-byte is found. This is not optimal.
However, string literals, and, in general, arrays, may be passed as references using template parameter deduction to keep their size:
template<std::size_t N>
void function_that_takes_a_constant_string ( const char (& s)[N] );
// Transparent, and the string's length is kept
function_that_takes_a_constant_string( "Hello, World!" );
The template function could serve as a proxy to another function, the real one, which would take a pointer to the string and its length, so that code exposure was avoided and the length was kept.
// Calling the wrapped function directly would be cumbersome.
// This wrapper is transparent and preserves the string's length.
template<std::size_t N> inline auto
function_that_takes_a_constant_string
( const char (& s)[N] )
{
// `s` decays to a pointer
// `N-1` is the length of the string
return function_that_takes_a_constant_string_private_impl( s , N-1 );
}
// Isn't everyone happy now?
function_that_takes_a_constant_string( "Hello, World!" );
Why isn't this used more broadly? In particular, why doesn't std::basic_string have a constructor with the proposed signature?
Note: I don't know how the proposed parameter is named; if you know how, please, suggest an edition to the question's title.
It's largely historical, in a sense. While you're correct that there's no real reason this can't be done (if you don't want to use your whole buffer, pass a length argument, right?) it's still true that if you have a character array it's usually a buffer not all of which you're using at any one time:
char buf[MAX_LEN];
Since this is usually how they're used, it seems needless or even risky to go to the trouble of adding a new basic_string constructor template for const CharT (&)[N].
The whole thing is pretty borderline though.
The trouble with adding such a templated overload is simple:
It would be used whenever the function is called with a static buffer of char-type, even if the buffer is not as a whole a string, and you really wanted to pass only the initial string (embedded zeroes are far less common than terminating zeroes, and using part of a buffer is very common): Current code rarely contains explicit decay from array to pointer to first element, using a cast or function-call.
Demo-code (On coliru):
#include <stdio.h>
#include <string.h>
auto f(const char* s, size_t n) {
printf("char* size_t %u\n", (unsigned)n);
(void)s;
}
auto f(const char* s) {
printf("char*\n");
return f(s, strlen(s));
}
template<size_t N> inline auto
f( const char (& s)[N] ) {
printf("char[&u]\n");
return f(s, N-1);
}
int main() {
char buffer[] = "Hello World";
f(buffer);
f(+buffer);
buffer[5] = 0;
f(buffer);
f(+buffer);
}
Keep in mind: If you talk about a string in C, it always denotes a 0-terminated string, while in C++ it can also denote a std::string, which is counted.
I believe this is being addressed in C++14 building on user defined string literals
http://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
#include <string>
int main()
{
//no need to write 'using namespace std::literals::string_literals'
using namespace std::string_literals;
std::string s2 = "abc\0\0def"; // forms the string "abc"
std::string s1 = "abc\0\0def"s; // form the string "abc\0\0def"
}
You can create helper class that will fix that without using overload for every function
struct string_view
{
const char* ptr;
size_t size;
template<size_t N>
string_view(const char (&s)[N])
{
ptr = s;
size = N;
}
string_view(const std::string& s)
{
ptr = s.data();
size = s.size() + 1; // for '\0' at end
}
};
void f(string_view);
main()
{
string_view s { "Hello world!" };
f("test");
}
You should expand this class for helper function (like begine and end) to simplify usage in your program.

Restrict passed parameter to a string literal

I have a class to wrap string literals and calculate the size at compile time.
The constructor looks like this:
template< std::size_t N >
Literal( const char (&literal)[N] );
// used like this
Literal greet( "Hello World!" );
printf( "%s, length: %d", greet.c_str(), greet.size() );
There is problem with the code however. The following code compiles and I would like to make it an error.
char broke[] = { 'a', 'b', 'c' };
Literal l( broke );
Is there a way to restrict the constructor so that it only accepts c string literals? Compile time detection is preferred, but runtime is acceptable if there is no better way.
There is a way to force a string literal argument: make a user defined literal operator. You can make the operator constexpr to get the size at compile time:
constexpr Literal operator "" _suffix(char const* str, size_t len) {
return Literal(chars, len);
}
I don't know of any compiler that implements this feature at this time.
Yes. You can generate compile time error with following preprocessor:
#define IS_STRING_LITERAL(X) "" X ""
If you try to pass anything other than a string literal, the compilation will fail. Usage:
Literal greet(IS_STRING_LITERAL("Hello World!")); // ok
Literal greet(IS_STRING_LITERAL(broke)); // error
With a C++11 compiler with full support for constexpr we can use a constexpr constructor using a constexpr function, which compiles to a non-const expression body in case the trailing zero character precondition is not fulfilled, causing the compilation to fail with an error. The following code expands the code of UncleBens and is inspired by an article of Andrzej's C++ blog:
#include <cstdlib>
class Literal
{
public:
template <std::size_t N> constexpr
Literal(const char (&str)[N])
: mStr(str),
mLength(checkForTrailingZeroAndGetLength(str[N - 1], N))
{
}
template <std::size_t N> Literal(char (&str)[N]) = delete;
private:
const char* mStr;
std::size_t mLength;
struct Not_a_CString_Exception{};
constexpr static
std::size_t checkForTrailingZeroAndGetLength(char ch, std::size_t sz)
{
return (ch) ? throw Not_a_CString_Exception() : (sz - 1);
}
};
constexpr char broke[] = { 'a', 'b', 'c' };
//constexpr Literal lit = (broke); // causes compile time error
constexpr Literal bla = "bla"; // constructed at compile time
I tested this code with gcc 4.8.2. Compilation with MS Visual C++ 2013 CTP failed, as it still does not fully support constexpr (constexpr member functions still not supported).
Probably I should mention, that my first (and preferred) approach was to simply insert
static_assert(str[N - 1] == '\0', "Not a C string.")
in the constructor body. It failed with a compilation error and it seems, that constexpr constructors must have an empty body. I don't know, if this is a C++11 restriction and if it might be relaxed by future standards.
No there is no way to do this. String literals have a particular type and all method overload resolution is done on that type, not that it's a string literal. Any method which accepts a string literal will end up accepting any value which has the same type.
If your function absolutely depends on an item being a string literal to function then you probably need to revisit the function. It's depending on data it can't guarantee.
A string literal does not have a separate type to distinguish it from a const char array.
This, however, will make it slightly harder to accidentally pass (non-const) char arrays.
#include <cstdlib>
struct Literal
{
template< std::size_t N >
Literal( const char (&literal)[N] ){}
template< std::size_t N >
Literal( char (&literal)[N] ) = delete;
};
int main()
{
Literal greet( "Hello World!" );
char a[] = "Hello world";
Literal broke(a); //fails
}
As to runtime checking, the only problem with a non-literal is that it may not be null-terminated? As you know the size of the array, you can loop over it (preferable backwards) to see if there's a \0 in it.
I once came up with a C++98 version that uses an approach similar to the one proposed by #k.st. I'll add this for the sake of completeness to address some of the critique wrt the C++98 macro.
This version tries to enforce good behavior by preventing direct construction via a private ctor and moving the only accessible factory function into a detail namespace which in turn is used by the "offical" creation macro. Not exactly pretty, but a bit more fool proof. This way, users have to at least explicitly use functionality that is obviously marked as internal if they want to misbehave. As always, there is no way to protect against intentional malignity.
class StringLiteral
{
private:
// Direct usage is forbidden. Use STRING_LITERAL() macro instead.
friend StringLiteral detail::CreateStringLiteral(const char* str);
explicit StringLiteral(const char* str) : m_string(str)
{}
public:
operator const char*() const { return m_string; }
private:
const char* m_string;
};
namespace detail {
StringLiteral CreateStringLiteral(const char* str)
{
return StringLiteral(str);
}
} // namespace detail
#define STRING_LITERAL_INTERNAL(a, b) detail::CreateStringLiteral(a##b)
/**
* \brief The only way to create a \ref StringLiteral "StringLiteral" object.
* This will not compile if used with anything that is not a string literal.
*/
#define STRING_LITERAL(str) STRING_LITERAL_INTERNAL(str, "")

const_cast in constructor acceptable

Is this a valid use of a const_cast ? I am using it in a constructor and it looks as follows:
KeyLiteObject(const char * extension, const char * swap_suffix)
: _extension(extension),
_swap_suffix(swap_suffix),
_swap_suffix_extension(swap_suffix)
{
const_cast<std::string*>(&_swap_suffix_extension)->append(_extension);
}
Yes, the strings will never change.
Assuming that _swap_suffix_extension is a const std::string then why not just do this:
KeyLiteObject(const char * extension, const char * swap_suffix)
: _extension(extension),
_swap_suffix(swap_suffix),
_swap_suffix_extension( std::string( swap_suffix ) + std::string( extension ) )
{
}
Then you can totally avoid the const_cast ...
Whenever possible avoid the const_cast, and here it is quite possible for any given type. Just create a helper function that takes the two arguments, composes the final value of the constant and use it in the initializer:
// header file
struct test {
const type x;
test( type const & a, type const & b );
};
// implementation file
namespace {
type compose( type const & arg1, type const & arg2 ) {
// calculate the actual value here
}
}
test::test(type const & a, type const & b)
: x( compose(a,b) )
{}
The cost of that is just writting a single free (static or in an unnamed namespace) function in the implementation file, and the result it readable if you choose a proper name for the function. In your case: concatenate or concat would be good choices.
While the use of const_cast in the example will not lead to undefined behavior, I would avoid it for personal reasons. Casts are cumbersome to write in C++ (compare with C or Java) for a reason: so that they will call the attention of the programmer: something weird is going on here! If you start sprinkling casts, then you will get used to seeing them, and they will become natural.