26

A simple C++ code:

int main(){
unsigned char* t="123";
}

on compilation with g++ gives following error:

invalid conversion from ‘const char*’ to ‘unsigned char*’ [-fpermissive]

Why?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
anupamD
  • 862
  • 1
  • 8
  • 21
  • Because a string literal is const. – Oliver Charlesworth Dec 26 '15 at 11:11
  • Thanks. So how to resolve it? Apart from using std::string – anupamD Dec 26 '15 at 11:13
  • And yes, if it is string literal, gcc does not give error on that. – anupamD Dec 26 '15 at 11:16
  • 1
    If you mean that using a C compiler doesn't give an error, that's (partially) because in C , `"123"` has type `char[4]` whereas in C++ it has type `const char[4]`. gcc , if not invoked in standard mode, also allows conversion between `char *` and `unsigned char *` without a cast – M.M Dec 27 '15 at 05:52
  • `const unsigned char* tmp= reinterpret_cast( "123" ); t = const_cast(tmp)`. – kgbook Apr 12 '19 at 18:22

4 Answers4

37

In C++ string literals have types of constant character arrays. For example string literal "123" has type const char[4].

In expressions with rare exceptions arrays are converted to pointers to their first elements.

So in this declaration

unsigned char* t="123";

the initializer has type const char *. There is no implicit conversion from const char * to unsigned char *

You could write

const unsigned char* t = reinterpret_cast<const unsigned char *>( "123" );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
4

Another approach, which gets you a modifiable unsigned char array as you originally wanted, is:

#include <cstdlib>
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    unsigned char ta[] = "123";
    unsigned char* t = ta;

    cout << t << endl;  // Or ta.

    return EXIT_SUCCESS;
}

You can add const to both declarations if you wish, to get const unsigned char without an explicit cast.

Davislor
  • 14,674
  • 2
  • 34
  • 49
0

Simply use

  1. just char* in place of unsigned char* during declaration

  2. char t[MAX_SIZE] = "123"; // MAX_SIZE should be defined earlier

  3. time tested strcpy() and strncpy functions

malang
  • 33
  • 9
0

Conversions from one type to another type is easy when you use self-defined macros. So here is a set of macros you can use across any platform (Windows, Linux, Solaris, AIX etc...)

#define M_ToCharPtr(p)        reinterpret_cast<char*>(p)                   // Cast to char*
#define M_ToWCharPtr(p)       reinterpret_cast<wchar_t*>(p)                // Cast to wchar_t*
#define M_ToConstCharPtr(p)   reinterpret_cast<const char*>(p)             // Cast to const char*
#define M_ToConstWCharPtr(p)  reinterpret_cast<const wchar_t*>(p)          // Cast to const wchar_t*
#define M_ToUCharPtr(p)       reinterpret_cast<unsigned char*>(p)          // Cast to unsigned char*
#define M_ToConstUCharPtr(p)  reinterpret_cast<const unsigned char*>(p)    // Cast to const unsigned char*
#define M_ToUCharPtr(n)       reinterpret_cast<unsigned char*>(n)          // Cast to unsigned char*
#define M_ToVoidPtr(p)        reinterpret_cast<void*>(p)                   // Cast to void*
#define M_ToConstVoidPtr(p)   reinterpret_cast<const void*>(p)             // Cast to const void*
#define M_ToIntPtr(n)         reinterpret_cast<int*>(n)                    // Cast to int*
#define M_ToConstIntPtr(p)    reinterpret_cast<const int*>(p)              // Cast to const int*
#define M_ToDoublePtr(n)      reinterpret_cast<double*>(n)                 // Cast to double*
#define M_ToConstDoublePtr(n) reinterpret_cast<const double*>(n)           // Cast to const double*
#define M_ToBoolPtr(n)        reinterpret_cast<bool*>(n)                   // Cast to bool*
#define M_ToConstBoolPtr(n)   reinterpret_cast<const bool*>(n)             // Cast to const bool*

// General Cast
#define M_To(T, p)            reinterpret_cast<T>(p)                       // Cast to T

In your case

const unsigned char* t = reinterpret_cast<const unsigned char *>("UCHAR TO CONST UCHAR");

is equivalent to

const unsigned char* t = M_ToConstUCharPtr("UCHAR TO CONST UCHAR");
SajithP
  • 592
  • 8
  • 19
  • 3
    These macros are not much shorter and only obfuscate the code. – Sopel Sep 03 '17 at 16:47
  • 2
    Why down vote? If it's wrong then it's acceptable but I'm trying to help coders who want to use macros in conversions. It's not a must to use macros, instead anyone can use the long literals... – SajithP Sep 04 '17 at 01:47