summaryrefslogtreecommitdiff
path: root/av.c
Commit message (Collapse)AuthorAgeFilesLines
* ‘Nonelems’ for pushing sparse array on the stackFather Chrysostomos2018-02-181-0/+13
| | | | | | | | | | | | | | | | | To avoid having to create deferred elements every time a sparse array is pushed on to the stack, store a magic scalar in the array itself, which av_exists and refto recognise as not existing. This means there is only a one-time cost for putting such arrays on the stack. It also means that deferred elements that live long enough don’t start pointing to the wrong array entry if the array gets shifted (or unshifted/spliced) in the mean time. Instead, the scalar is already in the array, so it cannot lose its place. This fix only applies when the array as a whole is pushed on to the stack, but it could be extended in future commits to apply to other places where we currently use deferred elements.
* store AV iterator as mg_len in more casesZefram2017-11-111-10/+10
| | | | | | | | | | | | | | | | | | | The iterator of an AV is an IV value attached to the AV via magic. It may be stored in the space used by mg_len, or it may be stored in separately allocated space referenced by mg_ptr. The former is more efficient, so should be preferred. The original code for AV iterators would use mg_len if IV was (the same size as) I32, because mg_len was of type I32. Since then mg_len has been increased to type SSize_t, but the conditional about how AV iterators are stored wasn't updated to match. As a result, on the now very common 64-bit builds we were missing out on the opportunity to use the more efficient form of storage. This commit updates the condition about how AV iterators are stored, to take account of the new type. In principle AV iterators ought to be of type SSize_t, and thus *always* storable as mg_len. But Perl_av_iter_p() is in the public API with its IV* return type, so there is a compatibility issue to address in changing that.
* av.c: silence compiler warningYves Orton2017-06-011-2/+3
| | | | | | | | | | av.c: In function ‘Perl_av_undef’: av.c:577:35: warning: ‘orig_ix’ may be used uninitialized in this function [-Wmaybe-uninitialized] PL_tmps_stack[orig_ix] = &PL_sv_undef; The warning is bogus, as we only use the orig_ix if real is true, and if real is true we will have set orig_ix. But it doesnt cost much to initialize it always and shut up the compiler.
* Change white space to avoid C++ deprecation warningKarl Williamson2016-11-181-1/+1
| | | | | | | | | | | | | | | | | | | | | | C++11 requires space between the end of a string literal and a macro, so that a feature can unambiguously be added to the language. Starting in g++ 6.2, the compiler emits a warning when there isn't a space (presumably so that future versions can support C++11). Unfortunately there are many such instances in the perl core. This commit fixes those, including those in ext/, but individual commits will be used for the other modules, those in dist/ and cpan/. This commit also inserts space at the end of a macro before a string literal, even though that is not deprecated, and removes useless "" literals following a macro (instead of inserting a blank). The result is easier to read, making the macro stand out, and be clearer as to the intention. Code and modules included with the Perl core need to be compilable using C++. This is so that perl can be embedded in C++ programs. (Actually, only the hdr files need to be so compilable, but it would be hard to test that just the hdrs are compilable.) So we need to accommodate changes to the C++ language.
* speed up AV and HV clearing/undeffingDavid Mitchell2016-10-261-12/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | av_clear(), av_undef(), hv_clear(), hv_undef() and av_make() all have similar guards along the lines of: ENTER; SAVEFREESV(SvREFCNT_inc_simple_NN(av)); ... do stuff ...; LEAVE; to stop the AV or HV leaking or being prematurely freed while processing its elements (e.g. FETCH() or DESTROY() might do something to it). Introducing an extra scope and calling leave_scope() is expensive. Instead, use a trick I introduced in my recent pp_assign() recoding: add the AV/HV to the temps stack, then at the end of the function, just PL_tmpx_ix-- if nothing else has been pushed on the tmps stack in the meantime, or replace the tmps stack slot with &PL_sv_undef otherwise (which doesn't care how many times its ref count gets decremented). This is efficient, and doesn't artificially extend the life of the SV like sv_2mortal() would. This commit makes this code around 5% faster: my @a; for my $i (1..3_000_000) { @a = (1,2,3); @a = (); } and this code around 3% faster: my %h; for my $i (1..3_000_000) { %h = qw(a 1 b 2); %h = (); }
* fixup some AV API pod descriptions.David Mitchell2016-09-271-11/+12
| | | | | | | | | | | | | | | | | | | In particular: * improve some of the "perl equivalent" entries; for example av_store() is *not* like $myarray[$key] = $val, since it replaces the stored SV with a different SV, rather than just updating the current SV's value. * Also change the "perl equivalent" variable names to match the function parameter names, e.g. $key rather than $idx. * Don't use 'delete' as a perl equivalent, since delete is discouraged on arrays. * You don't *have* to use av_store() to change undef values inserted by av_unshift; e.g. you could do av_fetch() then modify the returned undef SV; so just delete that sentence
* Revert "tmp fix for Bleadperl breaks Variable-Magic"David Mitchell2016-09-081-2/+1
| | | | | | | This reverts commit 8d168aaa014262c7f93944b76b84de99af3c5513. Variable-Magic 0.60 has been released, so this temp workaround is no longer required.
* tmp fix for Bleadperl breaks Variable-MagicDavid Mitchell2016-08-241-1/+2
| | | | | | | | | | | RT #128989 Prior to my commit v5.25.3-266-g1d7e644, in the absence of the SVs_RMG flag, av_fetch() used AvFILL() for -ve keys and AvFILLp() for positive keys. That commit changed it so they both use AvFILLp. This has broken Variable::Magic 0.59. As an interim measure, restore the old behaviour.
* av_fetch(): remove check for freed SVDavid Mitchell2016-08-191-5/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently av_fetch() has this extra test: if (AvREIFY(av) && SvIS_FREED(AvARRAY(av)[key])) { /* eg. @_ could have freed elts */ AvARRAY(av)[key] = NULL; /* 1/2 reify */ which basically says that if the array has the reify flag set (typically only @_ has this) and if the element being retrieved in it has been freed, then replace it with an undef value instead. This can be triggered with code like: sub f { $r = 0; my $var = $_[0]; } $r = do { my $x; \$x }; f($$r); which leaves $var as undef rather than causing a "panic: attempt to copy freed scalar". However, code like my ($var) = @_; *won't* get handled specially, and will still trigger the panic. It was added in 1996 as a result of this thread: From: Andreas Koenig <k@anna.in-berlin.de> Subject: SEGV with $_[0] and circular references Message-Id: <199608131528.RAA25965@anna.in-berlin.de> That was in the context of getting a SEGV - whereas now we get the "panic: attempt to copy freed scalar" instead. It was agreed in this thread that it could be removed: http://nntp.perl.org/group/perl.perl5.porters/239082
* av_fetch(): use less branches.David Mitchell2016-08-171-7/+14
| | | | | | | | | | | | | | | | | | | The code that handles negative array indexes and out-of-bounds negative indices used to require: 2 conditions for a +ve index 3 conditions for a -ve index After this commit, for the common case where the index is in bounds, it requires a single condition regardless of sign. For the less common case of out-of-bounds, it requires 2 conditions. Also, the one condition is more branch-predict friendly - it's whether the index is in bounds or not. Previously the first test was whether key < 0, and in code that does mixed signs, such as $a[0] + $a[-1], branch prediction could be tricky. It achieves this at the expense of a more complex expression for the key.
* av_fetch(): sprinkle UNLIKELY()David Mitchell2016-08-171-3/+3
|
* av_fetch(): optimise the negative index branch.David Mitchell2016-08-171-2/+4
| | | | | | For a negative index one conditional is redundant, since after determining that key < 0 and recomputing key as (AvFILLp(av) - key), key can't be > AvFILLp(av).
* av_fetch(): use AvFILLp rather than AvFILLDavid Mitchell2016-08-171-1/+1
| | | | | | | | | The point in the code which uses AvFILL will never be reached if the array is tied, so use AvFILLp insead, which directly accesses the xav_fill field. This only affects the $a[-N] branch: the $a[+N] branch already uses AvFILLp().
* av_fetch(): remove redundant conditionDavid Mitchell2016-08-171-3/+2
| | | | | At the point of testing for !AvARRAY(av)[key] if AvREIFY(av), it's already been confirmed that the array element isn't null.
* perlapi: Slight clarificationKarl Williamson2016-03-071-2/+2
| | | | | | | | | This changes to use 'transfer' to make clear that the reference count is unchanged. Some think that the previous wording 'take' is good as-is; some agree with me. Daniel Dragan has pointed out that 5 years ago I changed this line, while retaining 'take'. Given that 'transfer' is unambiguous to all, while 'take' is ambiguous to some, I'm making the change.
* Improve pod for [ah]v_(clear|undef)David Mitchell2015-10-201-7/+15
| | | | See [perl #117341].
* make EXTEND() and stack_grow() safe(r)David Mitchell2015-10-021-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit fixes various issues around stack_grow() and its two main wrappers, EXTEND() and MEXTEND(). In particular it behaves very badly on systems with 32-bit pointers but 64-bit ints. One noticeable effect of this is commit is that various usages of EXTEND() etc will now start to give compiler warnings - usually because they're passing an unsigned N arg when it should be signed. This may indicate a logic error in the caller's code which needs fixing. This commit causes several such warnings to appear in core code, which will be fixed in the next commit. Essentially there are several potential false negatives in this basic code: if (PL_stack_max - p < (SSize_t)(n)) stack_grow(sp,p,(SSize_t)(n)); where it incorrectly skips the call to stack_grow() and then the caller tramples over the end of the stack because it assumes that it has in fact been extended. The value of N passed to stack_grow() can also potentially get truncated or wrapped. Note that the N arg of stack_grow() is SSize_t and EXTEND()'s N arg is documented as SSize_t. In earlier times, they were both ints. Significantly, this means that they are both signed, and always have been. In detail, the problems and their solutions are: 1) N is a signed value: if negative, it could be an indication of a caller's invalid logic or wrapping in the caller's code. This should trigger a panic. Make it so by adding an extra test to EXTEND() to always call stack_grow if negative, then add a check and panic in stack_grow() (and other places too). This extra test will be constant folded when EXTEND() is called with a literal N. 2) If the caller passes an unsigned value of N, then the comparison is between a signed and an unsigned value, leading to potential wrap-around. Casting N to SSize_t merely hides any compiler warnings, thus failing to alert the caller to a problem with their code. In addition, where sizeof(N) > sizeof(SSize_t), the cast may truncate N, again leading to false negatives. The solution is to remove the cast, and let the caller deal with any compiler warnings that result. 3) Similarly, casting stack_grow()'s N arg can hide any warnings issued by e.g. -Wconversion. So remove it. It still does the wrong thing if the caller uses a non-signed type (usually a panic in stack_grow()), but coders have slightly more chance of spotting issues at compile time now. 4) If sizeof(N) > sizeof(SSize_t), then the N arg to stack_grow() may get truncated or sign-swapped. Add a test for this (basically that N is too big to fit in a SSize_t); for simplicity, in this case just set N to -1 so that stack_grow() panics shortly afterwards. In platforms where this can't happen, the test is constant folded away. With all these changes, the macro now looks in essence like: if ( n < 0 || PL_stack_max - p < n) stack_grow(sp,p, (sizeof(n) > sizeof(SSize_t) && ((SSize_t)(n) != n) ? -1 : n));
* perlapi: Add some S<>Karl Williamson2015-09-031-7/+7
| | | | | so that these constructs appear on a single output line for reader convenience.
* Various pods: Add C<> around many typed-as-is thingsKarl Williamson2015-09-031-8/+8
| | | | Removes 'the' in front of parameter names in some instances.
* Replace common Emacs file-local variables with dir-localsDagfinn Ilmari Mannsåker2015-03-221-6/+0
| | | | | | | | | | | | | | | | An empty cpan/.dir-locals.el stops Emacs using the core defaults for code imported from CPAN. Committer's work: To keep t/porting/cmp_version.t and t/porting/utils.t happy, $VERSION needed to be incremented in many files, including throughout dist/PathTools. perldelta entry for module updates. Add two Emacs control files to MANIFEST; re-sort MANIFEST. For: RT #124119.
* avoid integer overflow in Perl_av_extend_guts()David Mitchell2014-12-311-3/+13
| | | | | | | | | | | | | | | | | There were two issues; first the 'overextend' algorithm (add a fifth of the current size to the requested size) could overflow, and secondly MEM_WRAP_CHECK_1() was being called with newmax+1, which could overflow if newmax happened to equal SSize_t_MAX. e.g. $a[0x7fffffffffffffff] = 1 $a[5] = 1; $a[0x7fffffffffffffff] = 1 could produce under ASan: av.c:133:16: runtime error: signed integer overflow: 9223372036854775807 + 1 cannot be represented in type 'long' av.c:170:7: runtime error: signed integer overflow: 9223372036854775807 + 1 cannot be represented in type 'long'
* Remove duplicate apidoc entriesDavid Mitchell2014-12-171-4/+0
| | | | | Modify apidoc.pl to warn about duplicate apidoc entries, and remove duplicates for av_tindex and toLOWER_LC
* Documentation typo fixRafael Garcia-Suarez2014-08-061-1/+1
|
* Remove or downgrade unnecessary dVAR.Jarkko Hietaniemi2014-06-251-16/+0
| | | | | | | | You need to configure with g++ *and* -Accflags=-DPERL_GLOBAL_STRUCT or -Accflags=-DPERL_GLOBAL_STRUCT_PRIVATE to see any difference. (g++ does not do the "post-annotation" form of "unused".) The version code has some of these issues, reported upstream.
* PATCH: [perl #120386]: av_len documentationKarl Williamson2014-05-311-3/+8
| | | | I think I have incorporated everybody's concerns in this patch.
* refactor av_deleteDaniel Dragan2014-05-281-8/+8
| | | | | | | | Some bad code generation/bad optimization from VC caused me to clean this up. Dont write AvARRAY(av)[key] = NULL twice. It appears in 2 branches just as written VC asm wise. Don't call sv_2mortal on a NULL SV*. It works but less efficient. On VC2008 x64 -O1 this func dropped from 0x208 to 0x202 bytes of machine code after this patch.
* perlapi: Consistent spaces after dotsFather Chrysostomos2013-12-291-1/+1
| | | | plus some typo fixes. I probably changed some things in perlintern, too.
* Extend STRESS_REALLOC to move the stack with every EXTENDFather Chrysostomos2013-11-221-0/+9
| | | | | | This allows us easily to catch cases where the stack could move to a new memory address while code still holds pointers to the old loca- tion. Indeed, this causes test failures.
* [perl #120544] fix "goto" around var init error in av_extend_gutsDaniel Dragan2013-11-151-7/+14
| | | | | This fixes a Win32 Visual C 6 in C++ mode syntax error. See #120544 for the details.
* sub NEGATIVE_INDICES; + ↵Father Chrysostomos2013-11-041-1/+2
| | | | | | | | | | | $tied[-1] = crash This code in av.c, when trying to find $NEGATIVE_INDICES, was doing a direct stash element lookup--instead of going through the normal GV functions--and then expecting the returned value to be a GV. ‘sub NEGATIVE_INDICES’ creates a stash element that is a PV, not a GV, so it’s easy to make things crash.
* Use SSize_t for arraysFather Chrysostomos2013-08-251-18/+18
| | | | | | | | | | Make the array interface 64-bit safe by using SSize_t instead of I32 for array indices. This is based on a patch by Chip Salzenberg. This completes what the previous commit began when it changed av_extend.
* Use SSize_t when extending the stackFather Chrysostomos2013-08-251-4/+4
| | | | | | | | | | | | | | | | (I am referring to what is usually known simply as The Stack.) This partially fixes #119161. By casting the argument to int, we can end up truncating/wrapping it on 64-bit systems, so EXTEND(SP, 2147483648) translates into EXTEND(SP, -1), which does not extend the stack at all. Then writing to the stack in code like ()=1..1000000000000 goes past the end of allocated memory and crashes. I can’t really write a test for this, since instead of crashing it will use more memory than I have available (and then I’ll start for- getting things).
* [perl #7508] Use NULL for nonexistent array elemsFather Chrysostomos2013-08-201-32/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | This commit fixes bug #7508 and provides the groundwork for fixing several other bugs. Elements of @_ are aliased to the arguments, so that \$_[0] within sub foo will reference the same scalar as \$x if the sub is called as foo($x). &PL_sv_undef (the global read-only undef scalar returned by the ‘undef’ operator itself) was being used to represent nonexistent array elements. So the pattern would be broken for foo(undef), where \$_[0] would vivify a new $_[0] element, treating it as having been nonexistent. This also causes other problems with constants under ithreads (#105906) and causes a pending fix for another bug (#118691) to trig- ger this bug. This commit changes the internals to use a null pointer to represent a nonexistent element. This requires that Storable be changed to account for it. Also, IPC::Open3 was relying on the bug. So this commit patches both modules.
* Clarify av_shift API docsSteffen Mueller2013-07-201-3/+3
|
* change magic_methcall to use SV with shared hash valueRuslan Zakirov2013-06-301-6/+6
| | | | | | Perl_magic_methcall is not public API, so there is no need to add another function and we can just change function's arguments.
* Abolish STRANGE_MALLOC. Now all malloc()s are considered strange :-)Nicholas Clark2013-02-221-21/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | STRANGE_MALLOC was added in 5.002 beta 1 (4633a7c4bad06b47) as part of an work around for typical mallocs, which had a bad interaction with perl's allocation needs. Specifically, repeatedly extending an array and then creating SV heads (such as when reading lines of a file into an array) could end up with each reallocation for the array being unable to extend in place, needing a fresh chunk of memory, and the released memory not being suitable for use as more SV heads, so sitting unused. The solution was for perl to recycle the old array body as SV heads, instead of returning it to the system, passing the memory from the the AV code to the SV code using offer_nice_chunk(), PL_nice_chunk and PL_nice_chunk_size. STRANGE_MALLOC was actually a signal that the malloc() didn't need protecting from itself, and to disable the work around. offer_nice_chunk(), PL_nice_chunk and PL_nice_chunk_size were removed by commit 9a87bd09eea1d037 in Nov 2010, without any ill effects, hence the code used when STRANGE_MALLOC was *not* defined is essentially doing extra work for no benefits. From the lack of problems reported, one can assume that in the intervening 15 years malloc technology has got significantly improved, and it is probably better to be honest with it, rather than trying to second guess it. Hence remove all the non-STRANGE_MALLOC code, and leave everyone using the much simpler code. See also http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2005-11/msg00495.html http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2013-01/msg00126.html
* Add av_tindex() synonym for av_top_index()Karl Williamson2013-02-081-0/+2
| | | | | The latter is a somewhat less clumsy name. The old one is provided a a very clear name; the new one as a somewhat slangy version
* Inline av_top_index()Karl Williamson2013-02-081-16/+1
| | | | | This function is just an assert and a macro call. Avoid the function call overhead by making it inline.
* Change name 'av_top' to 'av_top_index'Karl Williamson2013-02-081-6/+6
| | | | | | | | In using the av_top() function created in a recent commit, I found myself being confused, and thinking it meant the top element of the array, whereas it really means the index of the top element of that array. Since the new name has not appeared in a stable release, it can be changed, without remorse, to include 'index' in it.
* Fix various minor pod issuesKarl Williamson2013-01-241-1/+1
| | | | | These were all uncovered by the new Pod::Checker, not yet in core. Fixing these will speed up debugging the new Checker.
* Add av_top() synonym for av_len()Karl Williamson2013-01-191-2/+22
| | | | av_len() is misleadingly named.
* perlapi: Clarify av_popKarl Williamson2013-01-121-2/+3
| | | | | | | This notes that the caller now has control of a reference count of the returned SV. Wording mostly suggested by Paul Evans
* Remove "register" declarationsKarl Williamson2012-11-241-10/+10
| | | | | | | This finishes the removal of register declarations started by eb578fdb5569b91c28466a4d1939e381ff6ceaf4. It neglected the ones in function parameter declarations, and didn't include things in dist, ext, and lib, which this does include
* av_exists: dont make a mortal never to use itbulk88 (via RT)2012-11-231-9/+12
| | | | | | | | | | | | | | | | | Make av_exists slightly smaller and faster by reducing the liveness of a mortal SV and using a NN SvTRUE_nomg. There were 3 cases, where this mortal would be created, yet a return happened and the mortal went unused and was wasted. So move the mortal creation point closer to where it is first used. Also var sv will never be null, so use a NN version of SvTRUE_nomg created in commit [perl #115870]. The retbool line isn't actually required for optimization reasons, but was created just in case something in the future changes or some unknown compiler does something inefficiently. For me with 32 bit x86 VC 2003, before av_exists was 0x1C2, after 0x1B8. Comment from committer: Includes SvTRUE_nomg_NN from [perl #115870].
* rmv context from Perl_croak_no_modify and Perl_croak_xs_usageDaniel Dragan2012-11-121-7/+7
| | | | | | | | | | | Remove the context/pTHX from Perl_croak_no_modify and Perl_croak_xs_usage. For croak_no_modify, it now has no parameters (and always has been no return), and on some compilers will now be optimized to a conditional jump. For Perl_croak_xs_usage one push asm opcode is removed at the caller. For both funcs, their footprint in their callers (which probably are hot code) is smaller, which means a tiny bit more room in the cache. My text section went from 0xC1A2F to 0xC198F after apply this. Also see http://www.nntp.perl.org/group/perl.perl5.porters/2012/11/msg195233.html .
* Don’t crash with $tied[-1] when array is tied to non-objFather Chrysostomos2012-10-281-58/+29
| | | | | The code for checking to see whether $NEGATIVE_INDICES is defined in the tie package was very fragile, and was repeated four times.
* Don’t skip tied EXISTS for negative array indicesFather Chrysostomos2012-10-281-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | This was broken in 5.14.0 for those cases where $NEGATIVE_INDICES is not true: sub TIEARRAY{bless[]}; sub FETCHSIZE { 50 } sub EXISTS { print "does $_[1] exist?\n" } tie @a, ""; exists $a[1]; exists $a[-1]; $NEGATIVE_INDICES=1; exists $a[-1]; $ pbpaste|perl5.12.0 does 1 exist? does 49 exist? does -1 exist? $ pbpaste|perl5.14.0 does 1 exist? does -1 exist? This was broken by 54a4274e3c.
* [perl #115440] Fix various leaks with fatal FETCHFather Chrysostomos2012-10-251-2/+9
| | | | | | | | | | | | | Various pieces of code were creating an SV and then assigning to it from a value that might be magical. If the source scalar is magical, it could die when magic is called, leaking the scalar that would have been assigned to. So we call get-magic before creating the new scalar, and then use a non-magical assignment. Also, anonhash and anonlist were doing nothing to protect the aggre- gate if an argument should die on FETCH, resulting in a leak.
* Stop padlists from being AVsFather Chrysostomos2012-08-211-27/+39
| | | | | | | | | | | | | | | | | | | | | In order to fix a bug, I need to add new fields to padlists. But I cannot easily do that as long as they are AVs. So I have created a new padlist struct. This not only allows me to extend the padlist struct with new members as necessary, but also saves memory, as we now have a three-pointer struct where before we had a whole SV head (3-4 pointers) + XPVAV (5 pointers). This will unfortunately break half of CPAN, but the pad API docs clearly say this: NOTE: this function is experimental and may change or be removed without notice. This would have broken B::Debug, but a patch sent upstream has already been integrated into blead with commit 9d2d23d981.
* Omnibus removal of register declarationsKarl Williamson2012-08-181-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This removes most register declarations in C code (and accompanying documentation) in the Perl core. Retained are those in the ext directory, Configure, and those that are associated with assembly language. See: http://stackoverflow.com/questions/314994/whats-a-good-example-of-register-variable-usage-in-c which says, in part: There is no good example of register usage when using modern compilers (read: last 10+ years) because it almost never does any good and can do some bad. When you use register, you are telling the compiler "I know how to optimize my code better than you do" which is almost never the case. One of three things can happen when you use register: The compiler ignores it, this is most likely. In this case the only harm is that you cannot take the address of the variable in the code. The compiler honors your request and as a result the code runs slower. The compiler honors your request and the code runs faster, this is the least likely scenario. Even if one compiler produces better code when you use register, there is no reason to believe another will do the same. If you have some critical code that the compiler is not optimizing well enough your best bet is probably to use assembler for that part anyway but of course do the appropriate profiling to verify the generated code is really a problem first.