to multi-character character constant or not

Started by
4 comments, last by fpsgamer 15 years, 8 months ago
I get "warning: multi-character character constant" on this line struct.id = 'raw'; my ids are 4 letters or less. like 'gun', 'bad1' 'hero' 'free', etc. i if id == 'word' a lot and sometimes id==id. I dont think i want to change them to strings and do strcmp everywhere.
<SkilletAudio> Your framerate proves your lack of manhood
Advertisement
This isn't pretty, but it is ok as long as you are aware of the implications, in particular, as long as you never plan to compile on or exchange constants with another platform.
The reason why you get this warning is that the constants may be different on another platform due to such features as endianess. Although it looks like it's 100% clear, it really isn't defined what you get.
So, as long as you know that there is no way you could get bitten by this, you can certainly go that way, it can be a considerable optimization, in some situations, over using strings.

You also have to be aware that it makes reverse engineering a lot easier too. If someone was to intercept your network traffic or read a memory dump, then 'hero' has a lot more of an immediate meaning than '7xm§' or '&&%!'. The same is true for strings, however.
Of course it is generally hard to prevent cheating, and given an interesting enough game to attract a dedicated and qualified enough audience, it is indeed impossible. But if just about everybody who knows what a hex editor is can read 'hero' without trouble, then the entry barrier to cheating is obviously a lot lower.

Having said that, I use enums, which gives me readable figures in the source and more or less arbitrary numbers elsewhere. It's not without its own set of traps, of course.
As long as it is safe, I don't see a problem with it.
However, from skimming the standard,

Quote:
An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter literal has type int and implementation-defined value

First, it has type int, which means there are only so many possible combinations it can hold (ok, so that number is over 4 billion, which is probably more than you need, but still, it means that not every literal can get a unique value), and second, the value is implementation-defined.

So if you want to use them, you should probably see if you can find anything in the compiler documentation on how they are handled.
The obvious way I'd do it I were writing the compiler, is to just parse the first 4 bytes (which gives you 32-bit, just like an int), and that means 'gun12' and 'gun13' would be equal.
And that would probably mean it's a very bad idea to use them as id's.

Would it be an option to use an enum instead?
This practice is semi acceptable in C.

But if you're using C++, why don't you use a typesafe solution? That means using the type system to distinguish between types instead of using an "id system".

eg: class Gun { ... };
I was thinking of using enums

but many of these values will be user (well, programmer) defined. I am basically tagging a struct and adding it to a manager. The ID is meaningless and only is used to check for a match. if i had 10 of these, 3 i written and 2 from 3 other programmers that i dont have to know about. why should there be a enum that we all need to update and keep track of.

that is my problem, mostly that it is meaningless and i dont want to keep track of others. Also generating an ID is bad bc i have to generate the same ID everytime i want that specific one in code. so, i could give it a random number. But i prefer using multichar const.

so its fine as long as we understand it is int and aware of its limitations (endianess and 4 letters, not moving out of ascii unless we accept less letters).

gun and hero were bad examples. its more of an id then name for a list of objects.
<SkilletAudio> Your framerate proves your lack of manhood
Quote:Original post by AcidZombie24
so its fine as long as we understand it is int and aware of its limitations (endianess and 4 letters, not moving out of ascii unless we accept less letters).

I didn't say up to 4 letter was safe, I said that's how I'd implement it. You don't know if that's what your compiler does. The value of a multi-character literal is implementation-defined.
So it's fine as long as you can dig up the bit of compiler documentation that says how they handle multi-character literals. :)

In any case, an alternative might be to use plain ints for your id's, and then use a std::map<string, int> to translate between id and the name string. That way you get both the efficient comparison (== on ints), and a way to assign names to them (just add an entry in the map say, idmap["hero"] = 42;)

Of course it's not perfect, but it would get rid of the limitations (and uncertainty) about multi-char constants, at least.
gun and hero were bad examples. its more of an id then name for a list of objects.

[Edited by - Spoonbender on August 17, 2008 6:08:07 AM]
I'm going to assume you're using C++, since you haven't specified otherwise ...

As I was saying before, this can be achieved without an id system. For every distinct item you want to support create a distinct type. Use of polymorphism if needed.

There is no reason to use id-based systems in languages that support strong/static typing.

I am also wary of the fact that you mentioned you need a "Manager". We cannot discern what, if anything, that manager does. Typically, whenever I encounter something called FooManager, it can be entirely factored out of the design.

So what exactly are you trying to achieve?

This topic is closed to new replies.

Advertisement