Explaning Image downsample

Started by
24 comments, last by Khatharr 11 years ago

...

Actually, that's undefined behaviour. You are not allowed to read from a member that wasn't written to directly. Also, casting a pointer to unsigned char to a structure is also undefined behaviour, since there is no guarantee by C++ that such cast is valid (e.g. due to alignment).

It's not defined by C++. It is defined by the compiler. I've never come across a compiler that had a problem doing it correctly, even without pragmas. Endianness may be a concern if you port it, but that's easily solved. In short, if you're iterating through units and casting them as byte arrays then you're already in the 'grey area' even though it's something that has to be done all the time. May as well make it easier to work with.

I should probably have used uint8_t there, though, since I used uint32_t.

Which compiler are you refering to? gcc casting a pointer of bytes to a pointer unions still breaks the strict aliasing rule. As for union "casting" have a look here: http://stackoverflow.com/questions/1812348/a-question-about-union-in-c/1812359#1812359

Advertisement

?

Maybe GCC has changed since I used it. I started using that kind of union for PSP dev with cygwin and g++ and later used it in VS2K8 and 2010.

This code runs under 2010 without complaint. I don't have g++ since my reformat, does this cause errors/warnings?


#include <stdio.h>

union uColor {
  unsigned int uint;
  struct {
    unsigned char alpha;
    unsigned char blue;
    unsigned char green;
    unsigned char red;
  };
  //unsigned char ary[4];
};

int main() {
  unsigned pixels[100];
  uColor* cols = (uColor*)pixels;
  for(int i = 0; i < 100; ++i) {
    cols.uint = 0;
    cols.alpha = 255;
  }
  printf("%08x\n", cols[12].uint);
  return 0;
}

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

This code runs under 2010 without complaint.

Indeed, VC implements nonstandard behaviour: http://msdn.microsoft.com/en-us/library/ms177255.aspx

quote name='Khatharr' timestamp='1364186046' post='5046427']

I don't have g++ since my reformat, does this cause errors/warnings?

[/quote]

It works, but it doesn't matter. Undefined behaviour may sometimes work.
In your case, I would just use std::memcpy. It's safe and VC will optimise it (into MOVs).

The thing is, I don't really see a problem with the cast. As long as the union is being formed correctly by the compiler it shouldn't cause any kind of problem. Just because it's not defined by the C++ standard doesn't necessarily mean it's anathema to all who dare.

In fact...

http://www.cplusplus.com/doc/tutorial/other_data_types/

says...


One of the uses a union may have is to unite an elementary type with an array or structures of smaller elements. For example:



union mix_t {
  long l;
  struct {
    short hi;
    short lo;
    } s;
  char c[4];
} mix;

As long as you're aware of the potential problems involved in union access, type puns, packing, alignment, endianness - none of which should be an issue here - the behavior should be consistent.

I don't understand how std::memcpy relates to this?

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

The thing is, I don't really see a problem with the cast. As long as the union is being formed correctly by the compiler it shouldn't cause any kind of problem. Just because it's not defined by the C++ standard doesn't necessarily mean it's anathema to all who dare.

Actually, it is. Unless you have an explicit specification of compiler behavior (like VC), you can't rely on it.


http://www.cplusplus.com/doc/tutorial/other_data_types/

says...

Quote

One of the uses a union may have is to unite an elementary type with an array or structures of smaller elements. For example:


union mix_t {
long l;
struct {
short hi;
short lo;
} s;
char c[4];
} mix;

The site is wrong.

As long as you're aware of the potential problems involved in union access, type puns, packing, alignment, endianness - none of which should be an issue here - the behavior should be consistent.

It shouldn't. The language gives no guarantees, so it can fail randomly and you have no right to complain.


I don't understand how std::memcpy relates to this?

It provides you with a safe approach. You can copy your bytes into a struct instead of casting. It's defined.

Okay, boss. I'll have to take your word for it.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

This topic is closed to new replies.

Advertisement