Author Topic: Compile error  (Read 11881 times)

sethjackson

  • Guest
Compile error
« on: February 05, 2006, 10:22:34 pm »
Hi I get this error

error: incompatible types in assignment of `int' to `unsigned char*[((unsigned int)((int)imageSize))]'

with this code......

Code: C++
  1. if (image.HasAlpha())
  2. {
  3.         unsigned long imageSize = image.GetWidth() * image.GetHeight() * 4;
  4.         unsigned char* imageData = image.GetData();
  5.         unsigned char* imageAlpha = image.GetAlpha();
  6.         unsigned char* data[imageSize];
  7.  
  8.         for (unsigned long index = 0; index < imageSize; index += 4)
  9.         {
  10.             memcpy(data, imageData, 3);
  11.  
  12.             imageData += 3;
  13.  
  14.             memcpy(data + 3, imageAlpha, 1);
  15.  
  16.             imageAlpha++;
  17.  
  18.             data += 4;
  19.         }
  20.  
  21.         gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.GetWidth(), image.GetHeight(),
  22.                           GL_RGB, GL_UNSIGNED_BYTE, data);
  23. }
  24.  


Help me please...... Sorry for the beginner question? I just don't get it I used to do stuff like increaseing the ptr with += all the time.....

EDIT:

Let me say that it fails on the line

Code: C++
  1. data += 4;
  2.  

 :P
« Last Edit: February 05, 2006, 10:27:33 pm by sethjackson »

sethjackson

  • Guest
Re: Compile error
« Reply #1 on: February 05, 2006, 10:35:42 pm »
Ok I fixed it now could someone tell me why this works???

Code: C++
  1. *(data) += 4;
  2.  

Offline polygon7

  • Multiple posting newcomer
  • *
  • Posts: 104
    • Home site
Re: Compile error
« Reply #2 on: February 05, 2006, 10:38:49 pm »
Hi,
this should work
Code: [Select]
if (image.HasAlpha())
{
        unsigned long imageSize = (image.GetWidth() * image.GetHeight())  << 2;
        unsigned char* imageData = image.GetData();
        unsigned char* imageAlpha = image.GetAlpha();
        unsigned char* data[imageSize];
 
        for (unsigned long index = 0; index < imageSize; index += 4)
        {
            memcpy(data, imageData, 3);
 
            imageData += 3;
 
            memcpy(data + 3, imageAlpha, 1);
 
            ++imageAlpha;
 
           (*data) += 4;
        }
 
        gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.GetWidth(), image.GetHeight(),
                          GL_RGB, GL_UNSIGNED_BYTE, data);
}
// Edit: Ah, you're faster :P
Code: [Select]
char* array[size] is the same as
Code: [Select]
char** array
« Last Edit: February 05, 2006, 10:41:15 pm by polygon7 »
best regards,
p7
 Free open source UML modeling tool: ArgoUML

sethjackson

  • Guest
Re: Compile error
« Reply #3 on: February 05, 2006, 10:40:22 pm »
 :lol: :lol: Read my post above. Exactly why does it work though? Thanks.  :D

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: Compile error
« Reply #4 on: February 05, 2006, 10:49:43 pm »
:lol: :lol: Read my post above. Exactly why does it work though? Thanks.  :D

You tried to assign an int to an unsigned char*. This does not work for sure. What do did is to de-reference the pointer. Then it works.

Why you cast before int and then unsigned int?

Anyway, do not use C-cast style. This is not a good idea in C++. You should use C++ cast style or better no cast at all (if possible).

Best wishes,
Michael

sethjackson

  • Guest
Re: Compile error
« Reply #5 on: February 05, 2006, 10:55:55 pm »
@polygon7

Why the
Code: C++
  1. << 2
instead of
Code: C++
  1.  * 4
?

This line

Code: C++
  1. unsigned long imageSize = (image.GetWidth() * image.GetHeight())  << 2;
  2.  

@Michael How to use a C++ style cast in this case??? Yes I know static_cast, dynamic_cast etc. How to use it here???

Offline polygon7

  • Multiple posting newcomer
  • *
  • Posts: 104
    • Home site
Re: Compile error
« Reply #6 on: February 05, 2006, 11:01:47 pm »
@polygon7

Why the
Code: C++
  1. << 2
instead of
Code: C++
  1.  * 4
?

This line

Code: C++
  1. unsigned long imageSize = (image.GetWidth() * image.GetHeight())  << 2;
  2.  
"<<" is shifting bits operator (shift left, SHL in assembly). SHL can be used for multiply by power of two (SHR, shift right for dividing by power of two).

x*2 == x <<1, x*4 == x <<2 ...

Bit shifting usually is faster then normal multiply.
« Last Edit: February 05, 2006, 11:07:12 pm by polygon7 »
best regards,
p7
 Free open source UML modeling tool: ArgoUML

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: Compile error
« Reply #7 on: February 05, 2006, 11:17:09 pm »
@Michael How to use a C++ style cast in this case??? Yes I know static_cast, dynamic_cast etc. How to use it here???

In your case and if I am not wrong, I would use the static_cast Operator:

Quote
static_cast<T> (expr)
To convert the expression expr to type T. Such conversions rely on static (compile-time) type information.

Anyway, I am not an expert in C++ cast as usually I used C cast until I discovered that are not so good (cast is already ugly, but C-cast is uglier). You can get some useful info here:


You can also have a look at this topic.

Michael

sethjackson

  • Guest
Re: Compile error
« Reply #8 on: February 06, 2006, 12:01:07 am »
Ok guys thanks. I learnt something today. :)

@Michael yeah I always use C++ casts instead of C casts. I couldn't figure out how to get it to work here. What type do I need to static_cast to?? I tried static_cast, but I couldn't figure out which type to cast to.  :P

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: Compile error
« Reply #9 on: February 06, 2006, 12:14:44 am »
@Michael yeah I always use C++ casts instead of C casts. I couldn't figure out how to get it to work here. What type do I need to static_cast to?? I tried static_cast, but I couldn't figure out which type to cast to.  :P

For example, you can use it to cast a double to an int:

Code: [Select]
double myDouble = 3.0;
int myInt = static_cast<int>(myDouble);

Anyway, be careful because static casts could be dangerous.

Have a look at the links I have suggested. There is a lot of examples and useful bla bla :).

Michael

sethjackson

  • Guest
Re: Compile error
« Reply #10 on: February 06, 2006, 03:05:57 am »
Ok I'll check it out tomorrow hopefully.  :lol:

sethjackson

  • Guest
Re: Compile error
« Reply #11 on: February 06, 2006, 07:18:09 pm »
I tried

Code: C++
  1. static_cast<unsigned char* []>(data) += 4;
  2.  

and it didn't work.

Code: [Select]
error: invalid static_cast from type `unsigned char*[((unsigned int)((int)imageSize))]' to type `unsigned char*[]'

What type (int, char, etc.) do I need to cast to???
« Last Edit: February 06, 2006, 07:20:02 pm by sethjackson »

sethjackson

  • Guest
Re: Compile error
« Reply #12 on: February 06, 2006, 07:23:17 pm »
Nevermind. This works, and better too I think. :)

Code: C++
  1. if (image.HasAlpha())
  2. {
  3.         unsigned long imageSize = image.GetWidth() * image.GetHeight() * 4;
  4.         unsigned char* imageData = image.GetData();
  5.         unsigned char* imageAlpha = image.GetAlpha();
  6.         unsigned char* data = new unsigned char[imageSize];
  7.  
  8.         for (unsigned long index = 0; index < imageSize; index += 4)
  9.         {
  10.             memcpy(data, imageData, 3);
  11.  
  12.             imageData += 3;
  13.  
  14.             memcpy(data + 3, imageAlpha, 1);
  15.  
  16.             ++imageAlpha;
  17.  
  18.             data += 4;
  19.         }
  20.  
  21.         gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.GetWidth(), image.GetHeight(),
  22.                           GL_RGB, GL_UNSIGNED_BYTE, data);
  23.  
  24.         delete[] data;
  25. }
  26.  

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: Compile error
« Reply #13 on: February 07, 2006, 10:42:10 am »
Hello,

When you use new you should check if the memory has been reserved or not. If I remember correctly the new sends a bad_allocation exception if it fails. Another version of new just a null pointer (which could or not be a better alternative :)).

Best wishes,
Michael

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5177
Re: Compile error
« Reply #14 on: February 07, 2006, 11:13:51 am »
Hello,

When you use new you should check if the memory has been reserved or not. If I remember correctly the new sends a bad_allocation exception if it fails. Another version of new just a null pointer (which could or not be a better alternative :)).

Best wishes,
Michael


Normally when new fails, it throws -> catch it.
There exist a no_throw new. I think it is not portable, the gurus (Sutter, ..) give the advice not to use it. So just forget you ever heard about it ;-)

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: Compile error
« Reply #15 on: February 07, 2006, 11:58:50 am »
Normally when new fails, it throws -> catch it.
There exist a no_throw new. I think it is not portable, the gurus (Sutter, ..) give the advice not to use it. So just forget you ever heard about it ;-)

Normally, I always use the throw new :). But, there was a mention of the no-throw new in the book C++Primer (4th Edition) written by
Stanley B. Lippman et al. I will give a check in the C++ standard book later. Until now, I have just found that you can overload the operator, but how this will influence the portability, it was not written :(.

Michael

sethjackson

  • Guest
Re: Compile error
« Reply #16 on: February 07, 2006, 07:39:29 pm »
How do I use try/catch?

Code: C++
  1.         unsigned char* data;
  2.  
  3.         // Try to allocate some memory.
  4.  
  5.         try
  6.         {
  7.              data = new unsigned char[imageSize];
  8.         }
  9.  
  10.         // Show an exception message if we can't allocate the memory we need.
  11.  
  12.         catch(bad_allocation)
  13.         {
  14.             wxSafeShowMessage(_("Exception"), _("Memory allocation failed! The application will terminate immediately..."));
  15.         }
  16.  
  17.  

Sorry I'm new to this type of error handling....  :P

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Compile error
« Reply #17 on: February 07, 2006, 07:48:33 pm »
You need to provide a type in the catch ( ) clause. Except for that, it's ok.

Alternatively, you can use catch ( ... ) if you want to catch all. Then, however, you don't know what you have caught (often, that's acceptable).

EDIT:
Oh yes... the reason why you have to provide a type is that you can catch different things from the same try block (in case that more than one thing can go wrong). The catch block whose type matches the exception thrown is executed and you get the exception similar to a function argument.
« Last Edit: February 07, 2006, 07:50:39 pm by thomas »
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Compile error
« Reply #18 on: February 07, 2006, 08:01:30 pm »
Another thing: You are using exceptions in an OpenGL application. I don't know what exactly you're programming there, but if it is something that is really CPU-intensive (which may happen to be the case here), then you should be aware that exceptions are not free.

Catching an exception (which luckily only happens in the exceptional case) takes a lot of CPU time, on the order of tens to hundreds of microseconds.
However, even if you do not throw and catch exceptions, your code runs somewhat slower (something on the order of 2-4%, depending on the compiler and the program). Often, this does not matter much, but then, sometimes it does. Thus, think clearly whether you really need exceptions in a CPU-intensive application.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: Compile error
« Reply #19 on: February 08, 2006, 02:16:50 am »
Thomas makes a good point but I don't you think you should throw them away out of hand.  Almost everyone spends time making "optimizations" on areas that don't need any.  I say use exceptions carefully and if you run into performance problems pull back there use.

Take a look at Ogre.  It is a high performance 3D rendering engine.  It uses exceptions, but only where they are appropriate, like when a resource fails to run or you have done something to crash the render system.

The overall important rule for exceptions to use them for program flow control, that means don't check for thing with exceptions.  This rough java snippet below is a good example of what not to do:

Code: Java
  1. int[] myArray = new int[10];
  2.  
  3. try {
  4.   int index = 0;
  5.   while(true) {
  6.     system.out.println(myArray[index])
  7.     index++;
  8.   }
  9.   // Finished the loop
  10. }
  11.  
  12.  
« Last Edit: February 08, 2006, 02:22:24 am by Game_Ender »

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Compile error
« Reply #20 on: February 08, 2006, 10:04:56 am »
Right, like I said, sometimes it does not matter, and sometimes it does. Although I disagree on Ogre ;)
Ogre is a good example where I think exceptions are actually out of place. It certainly works. And it works excellent, too. But the main purpose of Ogre is to create games. Today, the GPU usually has plenty of cycles left while on the other hand, the game is utterly CPU-bound. You have to try very hard to be GPU-bound (unless you write very very expensive shaders).
Thus, it seems to me that losing a couple of percent of CPU time to exception handling may not precisely be what you want to do.
Of course, things like scripting easily eat up 10-20 times as much CPU as EH, but you usually cannot do without scripting.

The problem with EH is that even if you only use exceptions where appropriate, you can only compile with or without exception handling, and unless you use compiler-specific attributes (such as nothrow), the compiler has a very hard time knowing where to add stack unwinding code and where not to (most will simply insert code everywhere).
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: Compile error
« Reply #21 on: February 08, 2006, 11:19:44 am »
There exist a no_throw new. I think it is not portable, the gurus (Sutter, ..) give the advice not to use it. So just forget you ever heard about it ;-)

I have had a look at the C++ Standard book and I have found that the two possibilities for the operator new are described and there are no constraints in using the throw-new instead of the nothrow-new. There is written something as: "If the program wishes...". Personally, I have never used the nothrow-new, but I prefer it, even if I have to specify nothrow, e.g.:

Code: [Select]
int* ndata = new(nothrow) int;
//do something with ndata
delete ndata;

I have also not found portability issues by searching with Google. May be this is due on how C++ standard compliant are the different compilers.

Michael

Offline jmccay

  • Almost regular
  • **
  • Posts: 202
Re: Compile error
« Reply #22 on: February 09, 2006, 02:31:29 am »
@polygon7

Why the
Code: C++
  1. << 2
instead of
Code: C++
  1.  * 4
?

This line

Code: C++
  1. unsigned long imageSize = (image.GetWidth() * image.GetHeight())  << 2;
  2.  
"<<" is shifting bits operator (shift left, SHL in assembly). SHL can be used for multiply by power of two (SHR, shift right for dividing by power of two).

x*2 == x <<1, x*4 == x <<2 ...

Bit shifting usually is faster then normal multiply.

I would like to add (because not everybody might know it) that there is one advantage to using the bit shifting operators over a normal multiplication/division.  On some systems (since I don't know all systems and my assembly language is rusty I will use "some"), the operator translates to an assembly/machine language command that is faster than multiplication & division.  It was/is a technique used by game developers for faster mathematics when manipulating images.  They would make the images multiples of 2 to be able to use it.

jmccay
OS: WinXP, Win98 SE, & sometimes Linux

a little light reading from the wxWidgets 2.6.2 readme: A detailed 2000-page reference manual is supplied in HTML, PDF and Windows Help form: see the docs hierarchy.

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1442
    • CenizaSOFT
Re: Compile error
« Reply #23 on: February 09, 2006, 03:16:04 am »
Well, if you take a look at the compiler's output, even without optimizations (GCC), using * 4 or << 2 generate the same code, but * 4 is still more readable.

For this code:
Code: C++
  1. b = a * 4;

The compiler outputs:
Code: ASM
  1. movl    -4(%ebp), %eax
  2. sall    $2, %eax
  3. movl    %eax, -8(%ebp)

There're many things compilers can handle by themselves, including such simple optimizations, and a few more advanced ones that can only be achieved in ASM.

Specifying optimizations (like -O3) will give you better results, like converting:
Code: C++
  1. b = a * 5;

into:
Code: ASM
  1. movl    -4(%ebp), %edx
  2. leal    (%edx,%edx,4), %eax
  3. movl    %eax, 4(%esp)

As you can see those early optimizations just make your code less readable for the same output and performance.