6

I'm trying to make a path (CGMutablePath) to be used for a shape node in SpriteKit (SKShapeNode). I'm running my code and it stops and says EXC_BREAKPOINT as if there's a breakpoint in the compiler, when there isn't one. Below is a screenshot of what I have.

Screenshot

As you can see, I have no breakpoint set in the compiler. It just tends to stop at line 31. There's nothing in the logs that give a reason for this crash, if there were one to begin with.

I'm used to Objective-C stopping in main.m with Thread 1: SIGABRT and an NSException in the log, but this just makes no sense. Can someone please explain what's wrong?

EDIT: here are more screenshots to prove I have no breakpoints set. When I get an exception, it simply throws a breakpoint.

Console log

UI

rmaddy
  • 314,917
  • 42
  • 532
  • 579
DDPWNAGE
  • 1,423
  • 10
  • 37

1 Answers1

6

That exception happens because arc4random() returns UInt32 and you are subtracting a value of that, which possibly causes a negative value, which is not representable as an unsigned integer.

To fix this you may want to cast the expression to Int32 before subtracting:

var y = CGFloat(self.size.height / 3) + CGFloat((Int32)(arc4random() % 100) - 50)

Regarding the x value above - you create CGFloat and only subtract after that and therefore not encounter the above situation. Therefore a different fix would be the following

var y = CGFloat(self.size.height / 3) + CGFloat(arc4random() % 100) - 50

You basically have to ensure that at the point where you subtract something you have no unsigned type present.

The annoying thing about this is that the compiler does not warn you and the code actually works sometimes, every time when arc4random returns something larger than 50 and will therefore not drift into the negative values...

Incorporating the feedback and suggestion that you should not use arc4random % something the best solution would be to use arc4random_uniform.

arc4random % something will not yield a proper distribution of the random values, while arc4random_uniform(something) does - this has already been discussed on SO before.

A final note: you probably should choose 101 as upper bound instead of 100 because both arc4random as well as arc4random_uniform produce a value between 0 and (upper-1), e.g. 0 and 99. If you subtract 50 you get a value between -50 and +49. Choosing 101 will yield the desired range of -50 to +50.

var y = CGFloat(self.size.height / 3) + CGFloat(arc4random_uniform(101)) - 50
Community
  • 1
  • 1
luk2302
  • 55,258
  • 23
  • 97
  • 137
  • Casting the `arc4random()` to an `Int32` worked for me. Still, why would it only say `EXC_BREAKPOINT?` – DDPWNAGE Jul 04 '15 at 21:03
  • @DDPWNAGE no idea why it gives you such a strange error. It does not happen at compile time, it happens at runtime - no idea what the "correct" or a better error message would be. – luk2302 Jul 04 '15 at 21:05
  • 3
    @DDPWNAGE See http://stackoverflow.com/questions/2611607/are-exc-breakpoint-sigtrap-exceptions-caused-by-debugging-breakpoints . `EXC_BREAKPOINT` is not caused by breakpoints. It's just a crash. Probably a raised exception. – Sulthan Jul 04 '15 at 21:40
  • 3
    Also: replace `arc4random() % 100` with `arc4random_uniform(100)`. – rob mayoff Jul 04 '15 at 21:49
  • @robmayoff thanks, I included that suggestion and bumped the bound up to 101. – luk2302 Jul 05 '15 at 12:10
  • I never even knew about module bias and the `arc4random_uniform(upperbound)` function until just now! Statistically, it wouldn't make a **huge** difference because my upper bound is 100, but it's still great to know that. Thank you! – DDPWNAGE Jul 05 '15 at 17:30
  • @DDPWNAGE It definitely makes a difference since it returns a UInt32 in the range of 0 to 4.294.967.295, modulo 100 will yield 0 to 95 a tiny bit more often than 96 to 99... not huge, but it is there ;) modulo 101 will have that point where the probabilities change after 67. – luk2302 Jul 05 '15 at 17:35
  • @luk2302 I thought it would just change the probability of getting 99. I'm converting to an Int32 either way. – DDPWNAGE Jul 05 '15 at 17:37
  • 1
    @DDPWNAGE I think we are mixing up two different things that were wrong with the randomness: 1. modulo in general is not recommended 2. the upper bound value never gets returned - two different things, both are solved with my last code line. – luk2302 Jul 05 '15 at 17:40