|
Zombywuf posted:Your compilers guess as to whether it should inline is probably as good as yours. It's a bit of a black art. Actually, no. Really lovely compilers like Metrowerks pretty much force you to forego inline functions and use macros to avoid function calls. VC++ and GCC which are far better in this area can still inject unwanted function calls, even when using stronger inline hints like __forceinline.
|
# ? Jul 5, 2008 21:37 |
|
|
# ? Jun 8, 2024 18:07 |
|
ehnus posted:Actually, no. Really lovely compilers like Metrowerks pretty much force you to forego inline functions and use macros to avoid function calls. VC++ and GCC which are far better in this area can still inject unwanted function calls, even when using stronger inline hints like __forceinline. I'd really like to see some kind of evidence to that effect, since I can't imagine GCC or MSVC would fail to inline functions that you request to inline (assuming they can be inlined and all that), unless you're loving around with compiler settings.
|
# ? Jul 5, 2008 21:47 |
|
I've fought the compilers may times on these fronts, off the top of my head the last time this was specifically an issue was for vectorized trigonometry routines. The only way I could get them inline consistently was to turn them into a macro
|
# ? Jul 5, 2008 22:40 |
|
gcc completely or mostly ignores 'inline' if you have optimizations on. Recent (4.3 or after) versions have decent inlining detection, but it was completely messed up before that. You really have to use __attribute__((always_inline)) sometimes.
|
# ? Jul 6, 2008 03:44 |
|
Sorry if this has been asked before. How can you get VS2005 to build a project that contains multiple 16-bit asm files and C++ files? I can get each individual file to compile separately; giving me obj files for each, but I can't build the project. I know it's because I'm using 16-bit assembly because I can build projects with 32-bit assembly just fine. Maybe if there was a way to use the 16-bit linker when building the project? Any help would be appreciated. Thanks.
|
# ? Jul 6, 2008 11:46 |
|
Can you set it to target a 16-bit machine in the project properties? It's under Linker -> Advanced.
|
# ? Jul 6, 2008 19:50 |
|
Avenging Dentist posted:Can you set it to target a 16-bit machine in the project properties? It's under Linker -> Advanced. I'm afraid there's no option for a 16-bit machine; only different processor types. E.G. x86, AM33, etc.
|
# ? Jul 6, 2008 22:19 |
|
Regalia posted:Sorry if this has been asked before. As far as I know know, you actually need to use an old linker, I'm pretty sure there is no switch. MASM 5.1 has one.
|
# ? Jul 6, 2008 23:44 |
|
Avenging Dentist posted:Macros are evil, and unless you absolutely have to, it's preferable to use an inline function to enforce type safety and all that good stuff. The 'macros are evil' is pretty lame, but I understand the type safety argument.
|
# ? Jul 7, 2008 00:37 |
|
Ugg boots posted:The 'macros are evil' is pretty lame, but I understand the type safety argument. I use macros plenty often, but only when I can't use anything else. Sometimes you have to do evil things to get the results you want, but it's something you should be cautious of. That said, you can get the best of both worlds if you're willing to write a few extra lines of code: code:
|
# ? Jul 7, 2008 01:07 |
|
sarehu posted:Here's an algorithm that scales better with respect to integer size. I don't think it's a good idea to use a macro. sarehu: do you have a reference/document for this? i think i saw that back in school, but i forgot about it. it was part of a lesson on how moving complex bitwise operations from functions to macros can speed up execution dramatically, due to having lots of constant expressions that can be optimized by the preprocessor. i'm using this for some asic dv code. my quick and dirty solution was this (32-bit version): code:
|
# ? Jul 7, 2008 08:02 |
|
That macro re-evalutates its first argument 15 times.
|
# ? Jul 7, 2008 13:27 |
|
Mustach posted:That macro re-evalutates its first argument 15 times. doesn't this get done at compile-time, so by the time it compiles its super fast code since it doesn't have to do an extra function call?
|
# ? Jul 7, 2008 13:55 |
|
I think the & 0x01 might screw up optimisations.
|
# ? Jul 7, 2008 14:21 |
|
bcrules82 posted:sarehu: do you have a reference/document for this? No.. I just made it up on the spot.
|
# ? Jul 7, 2008 14:35 |
|
Entheogen posted:doesn't this get done at compile-time, so by the time it compiles its super fast code since it doesn't have to do an extra function call? code:
Mustach fucked around with this message at 14:44 on Jul 7, 2008 |
# ? Jul 7, 2008 14:41 |
|
Mustach posted:Only if the argument is a constant expression. There stil won't be an "extra" function call since the macro just expands to a single statement, but EVEN_BITS_W(f()); expands to oh ok, i see what you are saying. even though macro is replaced by pre-compiler with whatever it is defined to, if data is a function call it will be evaluated 15 times.
|
# ? Jul 7, 2008 14:44 |
|
Entheogen posted:oh ok, i see what you are saying. even though macro is replaced by pre-compiler with whatever it is defined to, if data is a function call it will be evaluated 15 times. Yes, and what's worse, if that function call has any side-effects, those side-effects will be repeated 15 times. Imagine what would happen if f() were instead randomGenerator.nextNumber().
|
# ? Jul 7, 2008 15:04 |
|
Entheogen posted:oh ok, i see what you are saying. even though macro is replaced by pre-compiler with whatever it is defined to, if data is a function call it will be evaluated 15 times. Yes, the preprocessor does text substitution only. It's not compiling or optimizing anything.
|
# ? Jul 7, 2008 15:49 |
|
Question for the peanut gallery. How do you select a random integer from 0 to something higher than RAND_MAX? (Which I'm assuming is static) I'm guessing we're getting into algorithm territory... I come from a world where random numbers are floating in (0,1).
|
# ? Jul 7, 2008 18:06 |
|
Triple Tech posted:Question for the peanut gallery. How do you select a random integer from 0 to something higher than RAND_MAX? (Which I'm assuming is static) I'm guessing we're getting into algorithm territory... If RAND_MAX is a power of two minus one (which it usually is), you can generate two random integers, and consider them to be two halves of an integer with twice the number of bits set in RAND_MAX. This can be done with n random integers representing a number with n times the number of bits in RAND_MAX. For example, in the GNU C library where RAND_MAX is the largest representable int32_t (231-1, so 31 bits set), you generate two ints with rand(), and then OR them together to build a 62-bit integer which is equally random. (...assuming of course that you have or can create a datatype that can hold a 62-bit integer) If RAND_MAX is not 2x-1, then this isn't uniform, but there's probably a way around that if you're really interested in that corner case. Edit: It seems like you know this, but for lurkers in this thread, things that definitely do not work include... 1. Generate two numbers and add them together. Nope, the distribution will be biased in favor of numbers towards the middle of the range. In order to hit the extremes, both numbers must be either large or small simultaneously, which is less likely than other combinations. 2. Generate two numbers and multiply them together. Nope, (among other problems) the distribution will be biased towards even numbers. The result number will be even if either of the original numbers were, making the result three times more likely to be even than odd. The reason that the OR'ing method works is that if the original PRNG is any good, every bit in the original 31-bit numbers is just as random as every other bit, so if we generate 62 totally random bits, they're still totally random no matter what order we put them in, as long as we don't change them in any way (like by doing math with them). Smackbilly fucked around with this message at 18:37 on Jul 7, 2008 |
# ? Jul 7, 2008 18:16 |
|
Smackbilly posted:Yes, and what's worse, if that function call has any side-effects, those side-effects will be repeated 15 times. luckily i'm only using this with a const function, so hopefully the compiler optimizes to call it only once.
|
# ? Jul 7, 2008 18:42 |
|
bcrules82 posted:luckily i'm only using this with a const function, so hopefully the compiler optimizes to call it only once.
|
# ? Jul 7, 2008 19:23 |
|
Mustach posted:No guarantee there, e.g.: const int f(){ return rand(); } can rand() be called within a const method? anyways, i'm just returning a private variable.
|
# ? Jul 7, 2008 19:57 |
|
bcrules82 posted:can rand() be called within a const method? anyways, i'm just returning a private variable. Of course it can. The only constraint that const places on a method is that you can't change non-mutable member variables. Besides, if you're using C++, for the love of god just use an inline function.
|
# ? Jul 7, 2008 20:00 |
|
bcrules82 posted:can rand() be called within a const method? anyways, i'm just returning a private variable. A const member method only guarantees that the internal state of the object will not change (and even then there are legitimate reasons that the method might internally cast away constness for some operation). It does not at all preclude stateful library calls. In your case, yes, there is no logic-related problem with calling the accessor 15 times. There might be a performance hit if you are using this macro in a loop that runs many times because your compiler may choose not to inline the accessor for some reason. However the main thing we're pointing out is that one reason to avoid macros generally is because they are prone to bugs like this where the behavior of a poorly written "function macro" is different than the behavior of an equivalent function. Ideally, you shouldn't have to care if EVEN_BITS_W is a macro or a function call, because it should work the same way. In the case of the particular EVEN_BITS_W macro that was posted, this assumption is violated because the macro version re-evaluates the argument 15 times, whereas if it were written as a function, the argument would be guaranteed to only evaluate once. This means that if you ever later decide to re-use EVEN_BITS_W with an argument that is not a simple accessor, you do have to stop and carefully think about whether the argument can handle being evaluated 15 times with no ill effects.
|
# ? Jul 7, 2008 20:06 |
|
Avenging Dentist posted:
code:
Macros are annoying.
|
# ? Jul 7, 2008 23:36 |
|
Smackbilly posted:If RAND_MAX is a power of two minus one (which it usually is), you can generate two random integers, and consider them to be two halves of an integer with twice the number of bits set in RAND_MAX. More generally, generate two numbers x and y, and return (x * (RAND_MAX + 1)) + y. It is like writing a two digit number in the base RAND_MAX+1.
|
# ? Jul 8, 2008 01:03 |
|
Back again, with another beginner question. I'm having a bit of trouble with class-based states for a program. What I'm trying to achieve is to have a state manager class, that contains a vector of state classes, all of which are derived from a base class. Then I can push new states onto the end of the vector (i.e., to go into a submenu) or pop them off again (to go back up to the root menu). code:
The problem comes when I try to change the current state from within a state. code:
code:
code:
|
# ? Jul 11, 2008 13:27 |
|
It sounds a bit like you've just not declared the OnInit function in your base state class as virtual. You'll need to post more code to help pinpoint what's going wrong. Have you tried putting a breakpoint in the stateManager::ChangeState function and tracing into the OnInit function call to see where it ends up? Finally, I'm not 100% sure what you're trying to do with the logic in the changeState function, but it's almost certainly much more complicated than it needs to be. Split it into three functions: SetState, PushState and PopState.
|
# ? Jul 11, 2008 14:54 |
|
TSDK posted:It sounds a bit like you've just not declared the OnInit function in your base state class as virtual. You'll need to post more code to help pinpoint what's going wrong. That was the problem, thanks. I had a few more issues after I fixed that, but I realised that you're advice still applied. It looks like forgetting to set functions to virtual is something I need to get over. As for the breakpoint, I didn't (at the time) know what they were or how to do so. Since then I've figured out a rough idea; enough to use them, anyway. The ChangeState function was supposed to be work out how to switch state. So if the stack were empty, it'd just shove it in and run it. If the new state is identical to the current state, it does nothing, if the new state is identical to the next state back, it gets rid of the current state and resumes the next one. Then if none of those apply, it pauses the current state and shoves on the new one. I figured that this way, all you had to do was shove in the address of the state, and the function would work out the rest. Is this a bad way of going about things?
|
# ? Jul 11, 2008 16:10 |
|
Staggy posted:I figured that this way, all you had to do was shove in the address of the state, and the function would work out the rest. Is this a bad way of going about things? So if you have a PushState function, then it's always going to do exactly what you expect it to do: push a state on the stack - nothing more, nothing less.
|
# ? Jul 11, 2008 17:22 |
|
Staggy posted:State stuff. I'm a little confused about your program logic. Have you looked at the State Pattern? I recommend it highly. Your derived State classes should be handling events (each in their own way, relevant to that state) and simply notifying state transitions to the containing Manager class, effectively replacing themselves. The (abstract) base class (which should just be called "State", not "BaseState") defines a set of events for each state to respond to.
|
# ? Jul 11, 2008 21:14 |
|
Adhemar posted:I'm a little confused about your program logic. Have you looked at the State Pattern? I recommend it highly. That's what I'm trying to achieve, I think I just explained things badly. Each state - be it a menu, the game, etc. - is derived from a base class. The manager class keeps track of which state is active at the moment, as well as the ones before it. Each state can then tell the manager to change state. The base class defines various functions: OnInit(), OnRender(), OnLoop(), etc. Then the specific states expand on them, whilst the the state manager (mostly) simply calls the right function of the active state at the right time. However, like with most projects I start, I think I need to go back and start over now that I have a clearer vision of what it entails. Perhaps not 'expand' both the states and the manger class from the same base class.
|
# ? Jul 11, 2008 22:35 |
|
What's a way to determine the runtime of a program for something like a Project Euler problem?
|
# ? Jul 13, 2008 03:00 |
|
Insurrectum posted:What's a way to determine the runtime of a program for something like a Project Euler problem? man time
|
# ? Jul 13, 2008 03:06 |
|
Insurrectum posted:What's a way to determine the runtime of a program for something like a Project Euler problem? The way you always do. How is it any different?
|
# ? Jul 13, 2008 03:56 |
|
Plastic Jesus posted:man time sarehu posted:The way you always do. How is it any different? The way you always do? Explain to me how I have always determined how long it took a program to run. (But don't, because I just figured out to use GetTickCount() and subtract)
|
# ? Jul 13, 2008 04:08 |
|
I usually just run it and then count aloud to myself.
|
# ? Jul 13, 2008 04:08 |
|
|
# ? Jun 8, 2024 18:07 |
|
That Turkey Story posted:I usually just run it and then count aloud to myself. I'm talking about time differences in the 10 to 100s of milliseconds
|
# ? Jul 13, 2008 04:13 |