0

I never use macs or xcode but I need to now in order to build a C++ library for osx and ios. The C++ code builds fine for windows and android but in xcode I get hundreds of these red excmalation mark icons indicating this:

 Semantic issue
 cast from pointer to smaller type
'int' loses information

Here is an example of a line of code indicating this error

    fixturesArray.push_back((int)fixture->GetUserData());

Ive already had an issue building with unused variables and I removed a flag -Werror and this fixed that particular issue. Is there something similar I can do for this issue? I'm assuming the issue is warnings being treated as errors. Here are the other flags that are still there..

-Wall  -Wno-long-long -Wno-variadic-macros     -DNDEBUG -DDEBUG=0   

UPDATE: There were only about 10 or so instances of that error (the other 100's of things were warnings) If I change 'int' to 'int64' in all those cases then I can build. But I dont want to do that, I'm sure it wall cause issues, that is not how the program is supposed to work.

UPDATE2: Also leaving the code the way it is and just removing these flags lets me build
-Wno-long-long

Cœur
  • 37,241
  • 25
  • 195
  • 267
Guye Incognito
  • 2,726
  • 6
  • 38
  • 72
  • Show the declaration of `fixturesArray` and `GetUserData()`. – trojanfoe Sep 09 '14 at 13:09
  • potential duplicates: https://stackoverflow.com/questions/22419063/error-cast-from-pointer-to-smaller-type-int-loses-information-in-eaglview-mm and https://stackoverflow.com/questions/21232460/disabling-cast-from-pointer-to-smaller-type-uint32-t-error-in-clang – Cœur Dec 16 '17 at 15:29

2 Answers2

2

This code runs fine for windows because visual studio will create 32-bit binaries by default, and android is a 32-bit platform. In these platforms pointers are 32-bit, and int are 32 bit too, so it is possible to store a pointer in an int typed vector or variable.

Xcode will build by default both a 64-bit and 32-bit binary if you target Mac OS X, and the warning you get is actually telling you that on 64-bit platforms putting a pointer inside an int variable is not a good idea, because half of the pointer's value is lost, and you won't be able to retrieve it back later.

You can chase two different solutions in your case:

  • fix the code, changing int to intptr_t and fix whatever stops working because of that.
  • decide you don't want to fix it and so that you are not going to support 64-bit platform.

In the second case you can disable building a 64-bit binary and only use 32-bit ones on mac os by changing some options on xcode. To do this remove the x86_64 string from the "valid architectures" setting in target's "build settings" (if you can't find the setting, search google images for xcode valid architectures build setting)

pqnet
  • 6,070
  • 1
  • 30
  • 51
  • 1
    ... or you can avoid the cast altogether. – trojanfoe Sep 09 '14 at 13:26
  • @trojanfoe there may be reasons for which the array needs to be of integral types. I suggest never using C casts because they are a source of unexpected behavior, if needed use C++ styled casts instead, but that is a different issue than the one being discussed here – pqnet Sep 09 '14 at 13:28
  • Please specify some of these reasons. – trojanfoe Sep 09 '14 at 13:31
  • Hey thanks that'd be great! I do not want to build for 64 bit. – Guye Incognito Sep 09 '14 at 13:34
  • @trojanfoe for example if some library function expects an `int` vector and not a `void*` vector as parameter to store opaque data. – pqnet Sep 09 '14 at 13:40
  • So casting a pointer to an `int` is useful to this library function? I don't see how. – trojanfoe Sep 09 '14 at 13:42
  • @trojanfoe I googled it for you. See http://stackoverflow.com/questions/7146813/when-is-an-integer-pointer-cast-actually-correct and please clarify your question if it doesn't address your issue correctly. – pqnet Sep 09 '14 at 13:56
  • I just want to add that just building 32 bit thus hiding the problem and not fixing it will bring the pain back later on, when the code will silently fail and crash at random points. Also, in case the code shall ever be shipped, 64 bit support might be mandatory. – Eiko Sep 09 '14 at 14:10
  • In fact, I'd consider a library in 32bit deprecated, telling everyone: "end of life". Pointers are not ints. Why not simply make the array of the correct type and avoid all that (semantically incorrect) type-casting? – Eiko Sep 09 '14 at 14:16
  • @Eiko I think that it is pretty clear that telling the compiler not to create a 64-bit binary will actually result in a 32-bit only binary being generated, with all implication of the case. Whether a porting of an old codebase to a 64-bit platform is worthy or not is more of a project management issue than a programming issue, and thus out of topic for stack overflow (what would you do if someone asked `Should I have my engineer work to convert the code to 64-bit?` without further information?) – pqnet Sep 09 '14 at 14:21
  • 1
    @pqnet Of course. Just wanted to point out the possible consequences, which might not be obvious. Hiding bugs instead of fixing them is just a huge code smell. The compiler is your friend - you should be extremely thankful for every issue it shows. :-) – Eiko Sep 09 '14 at 14:26
  • @Eiko If the code works on the desired architectures I would not call it a bug. A software is bugged when it doesn't do what its specification requires it to do. An iOS application wouldn't usually compile without changes on Windows, but it is not a bug if a windows port is not required. – pqnet Sep 09 '14 at 14:31
  • @Eiko Of course in this case I think that it _will_ indeed become a bug in the future, because I expect 64-bit portability to become a requirement sooner or later, but it may not be the best idea to rewrite a great part of an unknown codebase (and thus introducing new bugs) just because it doesn't work on an architecture that _may_ be needed to support in the future. – pqnet Sep 09 '14 at 14:33
0

Well, it seems that GetUserData() returns a pointer. This seems to have a sizeof(void*) > sizeof(int) so casting cuts something off

Edit: If it works with an int64 this confirms my assumption (you seem to be sitting in front of a 64 bit machine). I am not sure what you are trying to do but casting pointers to integers is a bad idea. I would suggest that you make the fixturesArray a container of a suitable value type if you want this to work more independtly of the architecture.

hfhc2
  • 4,182
  • 2
  • 27
  • 56