Skip to main content
GameDev.net gamedev.net
🔒 Locked

(BYTE *) is evil?

Started by The C modest god Aug 3, 2006 at 6:21 AM 9 replies 1.7k views
Original Post
The C modest god
The C modest god
I have come to the conclusion that I should cast address into (BYTE *) as few as possible, if not to avoid completly. However, there are some things that seem to be impossible to be done without it. For instance, if I want to write a float variable into a file, but with the bytes in a switched order. How would I do that? Thanks in advance.
It's all about the wheel.Never blindly trust technoligy.I love my internal organs.Real men don't shower. Quote: Original post by Toolmaker Quote:
Evil Steve
Evil Steve
Quote:
Original post by The C modest god
I have come to the conclusion that I should cast address into (BYTE *) as few as possible, if not to avoid completly.
However, there are some things that seem to be impossible to be done without it.
For instance, if I want to write a float variable into a file, but with the bytes in a switched order. How would I do that?

Thanks in advance.


Firstly, what's wrong with casting to a BYTE*?

You could do it by casting to a DWORD* and using bitmasks and shifts, but that'll be no better than casting to a BYTE*...
ToohrVyk
ToohrVyk
There's nothing wrong with casting POD types to BYTE*. Now, if you were doing this with, say, an std::string, there would be reasons to complain. But a simple float is fine.

Alternatively, you could use:

  union {    float theFloat;    byte theBytes[4];  }
Deyja
Deyja
Theres nothing 'wrong' with casting a non-pod type to void* (or byte*, whatever) either. Hell; cast it to whatever you want. There are even times when it's 'right'. The issue comes with calling the constructors and destructors. You can't just copy the memory willy nilly. You have to explicitly use the classes copy constructor to make copies, and call other proper operators. You've taken the responsibility of managing that classes lifetime away from the compiler; you'd better manage it yourself - or else.
ToohrVyk
ToohrVyk
Quote:
Original post by Deyja
Theres nothing 'wrong' with casting a non-pod type to void* (or byte*, whatever) either.


There's a difference. Casting to void* is a common idiom used when you intend to cast back to the same type. When you cast to byte*:
  • If you only intend to cast back to the original type, why aren't you using void*, thus making maintenance easier by following an universal idiom?

  • If you intend to manipulate the individual bytes, then you're making a big mistake about the representation of objects in memory.


Consider the following:

class Example {  char value;public:  virtual ~Example() { }};Example e;byte* b = (byte*)e;b[0]; // What happens here?
Trap
Trap
Reading anything but the member last written in a union results in undefined behaviour, so does accessing data through a pointer with a type that differs from the original type (except for char* which are allowed to alias any data).

Many compilers guarantee the expected behaviour in those cases, but it is unportable in general. Google for GCC and -fno-strict-aliasing to find a lot of people who were suprised by this ;)

What is a BYTE?
Aardvajk
Aardvajk
Quote:
Original post by Trap
What is a BYTE?


Isn't it a Windows typedef for an unsigned char, like UCHAR?
Conner McCloud
Conner McCloud
Quote:
Original post by ToohrVyk
b[0]; // What happens here?

The memory at address b is read, and the result discarded [grin]

I know what you mean, though, and you are absolutely correct. The answer is: you don't know.

CM
Plasmarobo
Plasmarobo
Quote:
Original post by EasilyConfused
Quote:
Original post by Trap
What is a BYTE?


Isn't it a Windows typedef for an unsigned char, like UCHAR?


A BYTE is actually a unit of memory composed of 8 bits. A bit is a 0 or 1.
It is the second (I think) smallest unit of memory. (For every Gh that your processer has, it fires 1 billion bits through a second (or is it bytes a second?).

TERABYTE 1024 ^ 4 bytes
GIGABYTE 1024 * 1024 * 1024 bytes
MEGABYTE 1024 * 1024 bytes
KILLOBITE 1024 Bytes
BYTE 8 bits
Bit 0 or 1

_________Optimists see the glass as Half FullPessimists See the glass as Half EmptyEngineers See the glass as Twice as big as it needs to be
Conner McCloud
Conner McCloud
Quote:
Original post by Plasmarobo
A BYTE is actually a unit of memory composed of 8 bits. A bit is a 0 or 1.
It is the second (I think) smallest unit of memory. (For every Gh that your processer has, it fires 1 billion bits through a second (or is it bytes a second?).

TERABYTE 1024 ^ 4 bytes
GIGABYTE 1024 * 1024 * 1024 bytes
MEGABYTE 1024 * 1024 bytes
KILLOBITE 1024 Bytes
BYTE 8 bits
Bit 0 or 1

A byte is a unit of memory composed of 8 bits. A BYTE is a typedef of some sort, likely refering to whatever native type is composed of 8 bits. Your comment about Gh makes no sense, unless you are refering to GHz, in which case it is simply wrong. You describe Kibi, Mebi, Gibi, and Tebi (?) bytes. Kilobytes, et cetera, follow the same standard that the SI uses.

In C++, a byte is simply the size of a char, and is the smallest unit of memory that can be accessed by the program. This might be eight bits, it might be 64 bits, that's up to the processor.

CM
vininim
vininim
(kind of off-topic, but just to clarify)

Note that the concept of byte and word were initially informal, but you can put in terms of:
Byte: Smallest addressable part of a memory (whereas you have to do tricks to "access" a bit, for example). There were 1 and 36 bit bytes in history of architectures.
Word: Generally refers to the width of bits that most of a cpu units can access at a time.
Both byte and word are arch dependent.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.