Trouble compiling Ardynia on OS X


(Aernan) #1

Matt Grear asked me to post this here:

Arduino: 1.8.7 (Mac OS X), Board: "Arduino Leonardo"

In file included from /Users/aernan/Library/Arduino15/packages/arduino/hardware/avr/1.6.11/cores/arduino/Arduino.h:28:0,
                 from /Users/aernan/Documents/Arduino/libraries/Arduboy2/src/Arduboy2.h:10,
                 from sketch/src/game.cpp:1:
sketch/src/game.cpp: In member function 'void Game::loadEntitiesInRoom(uint8_t, uint8_t, uint8_t)':
sketch/src/game.cpp:341:24: error: invalid conversion from 'uint16_t {aka unsigned int}' to 'uint8_t** {aka unsigned char**}' [-fpermissive]
     uint8_t** rowPtr = pgm_read_word(entityDefs + y);
                        ^
sketch/src/game.cpp:342:24: error: invalid conversion from 'uint16_t {aka unsigned int}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]
     uint8_t* roomPtr = pgm_read_word(rowPtr + x);
                        ^
In file included from /Users/aernan/Library/Arduino15/packages/arduino/hardware/avr/1.6.11/cores/arduino/Arduino.h:28:0,
                 from sketch/src/entities/player.h:4,
                 from sketch/src/entities/player.cpp:1:
sketch/src/entities/player.cpp: In member function 'virtual void Player::render(uint8_t)':
sketch/src/entities/player.cpp:99:34: error: invalid conversion from 'void*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
         const uint8_t* itemBmp = pgm_read_ptr(secondaryItem_sprites + receivedItem);
                                  ^
In file included from /Users/aernan/Library/Arduino15/packages/arduino/hardware/avr/1.6.11/cores/arduino/Arduino.h:28:0,
                 from sketch/src/tileRoom.h:4,
                 from sketch/src/tileRoom.cpp:1:
sketch/src/tileRoom.cpp: In static member function 'static void TileRoom::renderTile(uint8_t, uint8_t, uint8_t, uint8_t)':
sketch/src/tileRoom.cpp:46:42: error: invalid conversion from 'uint8_t {aka unsigned char}' to 'TileDef' [-fpermissive]
     TileDef tile = tileId < 8 ? tileId : pgm_read_byte(mirroredTiles + (tileId - LowerLeftCorner) * 2);
                                          ^
In file included from /Users/aernan/Library/Arduino15/packages/arduino/hardware/avr/1.6.11/cores/arduino/Arduino.h:28:0,
                 from /Users/aernan/Documents/Arduino/libraries/Arduboy2/src/Arduboy2.h:10,
                 from sketch/src/inGameMenu.cpp:1:
sketch/src/inGameMenu.cpp: In member function 'void InGameMenu::render(Player&, uint8_t)':
sketch/src/inGameMenu.cpp:54:34: error: invalid conversion from 'void*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
         const uint8_t* itemBmp = pgm_read_ptr(secondaryItem_sprites + i + 1);
                                  ^
exit status 1
Error compiling for board Arduino Leonardo.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

(Matt) #2

I’ve never tried compiling the game with 1.8.7, and I’ve only every built it on Linux. I will try 1.8.7 in a couple hours and hopefully get the same errors :crossed_fingers:


(Matt) #3

I can only get the error if I manually compile and remove -Wno-error=narrowing, for me in 1.8.5 through 1.8.7, that setting is always set.

Not sure why it’s not set on OSX. I need to figure out how to get it not set when compiling on Linux without manually hacking stuff.

I have those errors fixed but want to co firm it really will compile.


#4

…it’s not just a matter of changing the ‘Compiler warnings:’ setting in Preferences?


(Matt) #5

Turns out it wasn’t -Wno-error=narrowing but rather -fpermissive. I was able to turn off permissive by making a change in the Arduino makefile.

People hit similar issues recently with Arduventure. It’s interesting that sometimes the Arduino IDE turns off permissive and sometimes it doesn’t. No matter what I tried I could not get it turned off in the IDE and I didn’t see anything that seemed relevant in the preferences.txt file.

I fixed all the warnings. @aernan if you grab the latest from github you should find it now builds. Let me know if it doesn’t.


(Pharap) #6

-fpermissive is a horrible flag, and I would argue that using it is Arduino’s biggest mistake of all (even more than the pointless byte and bool typedefs).

All it does is hide errors that are trying to warn you about bugs in your code (often in the form of undefined behaviour or implementation specific behaviour).

In your case it’s because you’re not doing explicit type conversions that you should be doing.

Solution:

uint8_t ** rowPtr = reinterpret_cast<uint8_t **>(pgm_read_word(&entityDefs[y]));

Solution:

uint8_t * roomPtr = reinterpret_cast<uint8_t *>(pgm_read_word(&rowPtr[x]));

Solution:

TileDef tile = static_cast<TileDef>(tileId < 8 ? tileId : pgm_read_byte(mirroredTiles + (tileId - LowerLeftCorner) * 2));

Et cetera.

(Basically, the best way to make sure your code compiles on all platforms is to get rid of all warnings.)


Also, I’d like to point out that this is why I try to introduce template functions into my programs to make things easier.

E.g.

template< typename T >
T * readPointer(const T * const progmem)
{
	return reinterpret_cast<const T *>(pgm_read_ptr(progmem));
}

Then you can just:

uint8_t * roomPtr = readPointer(&rowPtr[x]);

And the compiler will infer T for you (in this case T is uint8_t).
(Despite popular FUD about templates, the template function will be inlined so there’s absolutely no extra cost.)


(Matt) #7

Thanks for the tips, I need to read up on C++ style casting a bit, for now I’m still just doing it C style. Now that I have a reliable way to disable permissive I will do that. Now, how to get rid of the EEPROM warning? :slight_smile::expressionless::frowning:


#8

Tested Arduino 1.8.7 with Homemade package installed on a MacMini running OSX Sierra and it compiled Ardynia without errors (but lots of warnings ofcourse) Wasn’t able to upload it as I didn’t have my Arduboy with me at work.


(Matt) #9

at this point the warnings should just be the EEPROM warning and one warning about an unused enum value in a switch statement.


#10

I ran the test about 6-7 hours ago (back home with a burger filled tummy now :stuck_out_tongue: )


(Pharap) #11

I avoid C-style casting like the plague because of the danger of casting away a const by mistake.

Also I have a self-imposed rule that I’m not allowed to use C-style casting unless I can remember the order that it attempts the C++-style casts in, and I never can so I never do.

In practice I find that I only ever need static_cast and reinterpret_cast, so I follow the rule of thumb "reinterpret_cast for pointers, static_cast for everything else", and 99% of the time that holds true.


As for dynamic_cast and const_cast - if you have to ask how they work, you almost certainly don’t need them.

I don’t think anyone would need a dynamic_cast on Arduboy anyway, and I’m not even sure if it would work - I’m pretty sure runtime type information is disabled by the Arduino IDE, which should prevent dynamic_cast from working.

I genuinely hope nobody ever needs const_cast.
If you’re in a situation where you need const_cast then someone has seriously screwed up and you’ve got bigger problems than understanding what const_cast does.


For the most part people have given up yelling at them about this.

The really sad thing is that the EEPROM library wastes space compared to the equivalent avr-libc functions (documented here).

Nobody uses the eeprom ref/eeprom pointer implementations either, so in my opinion the whole EEPROM library is a big, wasted mess.

That’s why I wrote my own wrapper which still has some nice templated functions but doesn’t suffer from the same progmem overhead/pitfalls.

Use a default: break;.


(Aernan) #12

I was able to install arduino environment on windows 7 (vm) and compile without warnings and uploaded the game. The game is fun. :slight_smile: