0

I want to take advantage of this post to understand in more detail how unsigned and signed work regarding pointers. The problem I am having is that I have to use a function from opengl called glutBitmapString which takes as parameter a void* and const unsigned char*. I am trying to convert a string to a const unsigned c_string.

Attempt:

string var = "foo";
glutBitmapString(font, var.c_str());

However, that's not quiet right because the newly generated c_str is signed. I want to stay away from casting because I think that will cause narrowing errors. I think that unsigned char and signed char is almost the same thing but both do a different mapping. Using a reinterpret_cast comes to mind, but I don't know how it works.

genpfault
  • 51,148
  • 11
  • 85
  • 139
TheMathNoob
  • 307
  • 3
  • 16
  • 1
    Good reading: [When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?](https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used) – user4581301 Aug 05 '17 at 00:23
  • reinterpret_cast is known to be dangerous. That's I want to stay away from it. In this case a reinterpret_cast is reasonable because I have to cast a pointer, but I don't know if I would get the same result. – TheMathNoob Aug 05 '17 at 00:26
  • 1
    @user4581301 Short answer: almost never. Kidding. Semi-kidding. – Ron Aug 05 '17 at 00:27
  • 1
    `reinterpret_cast`, @Ron? Agreed. Only if absolutely unavoidable. Sucker is the Hammer of God. It will make the circle fit in the square hole and odds are the program will misbehave as a result. For this, Kinda depends. ASCII is only defined to 127, so signed and unsigned don't matter. If you've got extended ASCII going on, there is room for interpretation error. – user4581301 Aug 05 '17 at 00:38

2 Answers2

4

I would use reinterpret_cast:

glutBitmapString(font, reinterpret_cast</*const*/unsigned char*>(var.c_str()));

it is a rare case where strict aliasing rule is not broken.

Negative values will be interpreted as unsigned (so value + 256).

Jarod42
  • 203,559
  • 14
  • 181
  • 302
2

In this particular case (and almost all others), signed vs. unsigned refer to the content pointed at by the pointer.

unsigned char* == a pointer to (unsigned char(s))

signed char* == a pointer to (signed char(s))

Generally, no one is treating 0xFF as a numeric value at all, and signed vs. unsigned doesn't matter. Not always the case and sometimes with strings people sloppily use unsigned vs signed to refer to one type over another....but you're probably safe just casting the pointer.

If you're NOT safe casting the pointer, it means your data that is pointed to is invalid/is in the wrong format.

To clarify on unsigned char vs. signed char, check this out: https://sqljunkieshare.files.wordpress.com/2012/01/extended-ascii-table.jpg

Is the char 0xA4 positive or negative? It's neither. It's ñ. It's not a number at all. So signed vs. unsigned doesn't really matter. Make sense?

zzxyz
  • 2,953
  • 1
  • 16
  • 31
  • it worked, so it means casting pointers implies casting the elements it points to. – TheMathNoob Aug 05 '17 at 00:37
  • always. yes. Everything about the declaration of a pointer but the `*` tells you WHAT it is pointing at. – zzxyz Aug 05 '17 at 00:42
  • 1
    `0xA4` is an integral value. If it can be stored in a `char` (which is not guaranteed) it is still an integral value. – Peter Aug 05 '17 at 03:34
  • 1
    @Peter: `0xA4` is a representation of a bit pattern. The fact that it more natively represents an integral value is an unfortunate coincidence, and a limitation of how we communicate. – Mooing Duck Apr 29 '21 at 16:04