8000 msvc9 32-bit builds are unusable · Issue #6428 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

msvc9 32-bit builds are unusable #6428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
cgohlke opened this issue Oct 8, 2015 · 48 comments · Fixed by #6438
Closed

msvc9 32-bit builds are unusable #6428

cgohlke opened this issue Oct 8, 2015 · 48 comments · Fixed by #6438

Comments

@cgohlke
Copy link
Contributor
cgohlke commented Oct 8, 2015

numpy-1.10.0 compiled with Visual Studio 2008 for 32-bit Python fails many tests (only part of the output is shown):

Running unit tests for numpy
NumPy version 1.10.0
NumPy relaxed strides checking option: True
NumPy is installed in X:\Python27\lib\site-packages\numpy
Python version 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)]
nose version 1.3.7
....F.FF.E........................................................................
<snip>
======================================================================
FAIL: test_api.test_array_array
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "X:\Python27\lib\site-packages\numpy\core\tests\test_api.py", line 75, in test_array_array
    assert_equal(dat, [49.0, 46.0, 48.0])
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 295, in assert_equal
    return assert_array_equal(actual, desired, err_msg, verbose)
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 782, in assert_array_equal
    verbose=verbose, header='Arrays are not equal')
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 708, in assert_array_compare
    raise AssertionError(msg)
AssertionError:
Arrays are not equal

(mismatch 100.0%)
 x: array([ 49.,  46.,  48.])
 y: array([ 49.,  46.,  48.])

======================================================================
FAIL: test_api.test_array_astype
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "X:\Python27\lib\site-packages\numpy\core\tests\test_api.py", line 187, in test_array_astype
    assert_equal(a, b)
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 295, in assert_equal
    return assert_array_equal(actual, desired, err_msg, verbose)
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 782, in assert_array_equal
    verbose=verbose, header='Arrays are not equal')
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 708, in assert_array_compare
    raise AssertionError(msg)
AssertionError:
Arrays are not equal

(mismatch 100.0%)
 x: array([[ 0.,  1.,  2.],
       [ 3.,  4.,  5.]], dtype=float32)
 y: array([[0, 1, 2],
       [3, 4, 5]])
<snip>
======================================================================
FAIL: test_inplace_floor_division_array_type (test_core.TestMaskedArrayInPlaceArithmetics)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\numpy\ma\tests\test_core.py", line 2244, in test_inplace_floor_division_array_type
    assert_equal(len(w), 0, "Failed on type=%s." % t)
  File "X:\Python27\lib\site-packages\numpy\ma\testutils.py", line 130, in assert_equal
    raise AssertionError(msg)
AssertionError:
Items are not equal: Failed on type=<type 'numpy.int64'>.
 ACTUAL: 1
 DESIRED: 0

----------------------------------------------------------------------
Ran 5440 tests in 34.344s

FAILED (KNOWNFAIL=7, SKIP=9, errors=498, failures=221)

Reverting #6252 fixes this problem.

Builds using msvc9 64-bit, msvc10, msvc14, and icl do not show this problem.

I did not notice this before because I was testing the RCs with the Intel, not msvc, compilers.

@charris
Copy link
Member
charris commented Oct 8, 2015

@juliantaylor Thoughts?

@charris
Copy link
Member
charris commented Oct 8, 2015

Note that one quick solution is to revert the patch. @juliantaylor What compilers were affected by the original code?

@charris
Copy link
Member
charris commented Oct 9, 2015

@cgohlke Sounds almost like a compiler bug. @juliantaylor I suppose we could put an #if somewhere in there and check for compiler version and 32 bit platform rather than revert the patch, which would seem to introduce an error with gcc 3.4.

@juliantaylor
Copy link
Contributor

can we get a disassembly of these functions?
I don't see how this could get miscompiled and the original code not. Unless I'm overlooking another undefined behaviour here?

@juliantaylor
Copy link
Contributor

btw I do have a windows32 (virtual) box, next time you can ask me to test the binaries you produced before releasing them.

@juliantaylor
Copy link
Contributor

oh wait out binaries are built with mingw and work (I assume), so this is not actually such a big problem

@charris
Copy link
Member
charris commented Oct 9, 2015

@juliantaylor that's why I haven't taken down 1.10.0 on Sourceforge yet. But that doesn't mean it can't affect someone, somewhere. We could also solve the problem by dropping Python 2.6 support...

@charris
Copy link
Member
charris commented Oct 9, 2015

Looks like Python 2.6 was officially retired with 2.6.9 released in Oct 2013.

@juliantaylor
Copy link
Contributor

yes we should try to fix it, though I don't really know how, unless we understand the problem it would have to be a versioned ifdef for msvc9. The old code invokes undefined behaviour so we do not want to just revert the change.
But the number of people who can't use our binaries and rebuild numpy from source for python2 is probably relatively small.

I think dropping py2 (and < py3.5) support on windows is not unreasonable from a technical standpoint. unfortunately the py2.7 downloads still exceed py3 by a large margin.

@charris
Copy link
Member
charris commented Oct 9, 2015

Oh, right. Looks like python 2.7 also uses msvc9. Darn.

@charris
Copy link
Member
charris commented Oct 9, 2015

All Pythons up to 3.2, in fact. I'd like to drop 3.2 at some point but I expect it will be a long time before we can drop 2.7.

@charris
Copy link
Member
charris commented Oct 9, 2015

There is this http://www.microsoft.com/en-us/download/details.aspx?id=44266, which is a snapshot of 9.0.0.30729. @cgohlke What version of msvc9 are you using?

@cgohlke
Copy link
Contributor Author
cgohlke commented Oct 9, 2015

I am using Visual Studio 2008 Pro with SP1 installed, that is version 15.00.30729.01.

@cgohlke
Copy link
Contributor Author
cgohlke commented Oct 9, 2015

Here are the assembly output with and without #6252:

_TEXT   ENDS
PUBLIC  __real@00000000
;   COMDAT __real@00000000
CONST   SEGMENT
__real@00000000 DD 000000000r           ; 0
; Function compile flags: /Ogtpy
CONST   ENDS
_TEXT   SEGMENT
_tmp$ = -4                      ; size = 4
_a$ = 8                         ; size = 4
_b$ = 12                        ; size = 4
_sse2_ordered_cmp_equal_FLOAT PROC

; 541  : {

    push    ebp
    mov ebp, esp
    and esp, -16                ; fffffff0H
    sub esp, 16                 ; 00000010H

; 542  :     @type@ tmp;
; 543  :     @vtype@ v = @vpre@_@VOP@_@vsufs@(@vpre@_load_@vsufs@(&a),
; 544  :                                      @vpre@_load_@vsufs@(&b));
; 545  :     @vpre@_store_@vsufs@(&tmp, v);
; 546  :     return !(tmp == 0.);

    fldz
    xorps   xmm0, xmm0
    movss   xmm0, DWORD PTR _a$[ebp]
    xorps   xmm1, xmm1
    movss   xmm1, DWORD PTR _b$[ebp]
    cmpeqss xmm0, xmm1
    movss   DWORD PTR _tmp$[esp+16], xmm0
    fcomp   DWORD PTR _tmp$[esp+16]
    fnstsw  ax
    test    ah, 68                  ; 00000044H
    jnp SHORT $LN3@sse2_order
    mov eax, 1

; 547  : }

    mov esp, ebp
    pop ebp
    ret 0
$LN3@sse2_order:

; 542  :     @type@ tmp;
; 543  :     @vtype@ v = @vpre@_@VOP@_@vsufs@(@vpre@_load_@vsufs@(&a),
; 544  :                                      @vpre@_load_@vsufs@(&b));
; 545  :     @vpre@_store_@vsufs@(&tmp, v);
; 546  :     return !(tmp == 0.);

    xor eax, eax

; 547  : }

    mov esp, ebp
    pop ebp
    ret 0
_sse2_ordered_cmp_equal_FLOAT ENDP
; Function compile flags: /Ogtpy
_tmp$ = -4                      ; size = 4
_a$ = 8                         ; size = 4
_b$ = 12                        ; size = 4
_sse2_ordered_cmp_equal_FLOAT PROC

; 541  : {

    push    ebp
    mov ebp, esp
    and esp, -16                ; fffffff0H
    sub esp, 16                 ; 00000010H

; 542  :     @type@ tmp;
; 543  :     @vtype@ v = @vpre@_@VOP@_@vsufs@(@vpre@_load_@vsufs@(&a),
; 544  :                                      @vpre@_load_@vsufs@(&b));

    xorps   xmm0, xmm0
    movss   xmm0, DWORD PTR _a$[ebp]
    xorps   xmm1, xmm1
    movss   xmm1, DWORD PTR _b$[ebp]
    cmpeqss xmm0, xmm1

; 545  :     @vpre@_store_@vsufs@(&tmp, v);

    movss   DWORD PTR _tmp$[esp+16], xmm0

; 546  :     return sizeof(@type@) == 4 ?
; 547  :         (*(npy_uint32 *)&tmp) & 1 : (*(npy_uint64 *)&tmp) & 1;

    mov eax, DWORD PTR _tmp$[esp+16]
    and eax, 1

; 548  : }

    mov esp, ebp
    pop ebp
    ret 0
_sse2_ordered_cmp_equal_FLOAT ENDP

@charris
Copy link
Member
charris commented Oct 9, 2015

xor eax, eax, looks like it always returns 0. @juliantaylor Is there a special reason for the construction return !(tmp == 0.); ?

NVM, I missed the jump.

@charris
Copy link
Member
charris commented Oct 9, 2015

However, there is an extra compare in the new version. Although it it uses test and apparently looks specifically at the bits in tmp. Could be that doesn't handle NaNs correctly?

@charris
Copy link
Member
charris commented Oct 9, 2015

I'm going to guess the !(tmp == 0.) is optimized to tmp != 0., which is not quite the same thing.

@charris
Copy link
Member
charris commented Oct 9, 2015

I wonder what is different with 64 bits?

@juliantaylor
Copy link
Contributor

nan shouldn't really matter, in fact if the comparison is true tmp is always nan but nan is not equal 0
the function is not inlined?
I think that code looks fine, but it might go wrong during inlining

the difference for 64 bit is probably that it doesn't use the x87 fpu which will lead to different code generation

@charris
Copy link
Member
charris commented Oct 9, 2015

Easy to check by not inlining it.

@cgohlke
Copy link
Contributor Author
cgohlke commented Oct 9, 2015

It seem compiling with /arch:SSE2 flag fixes this and all other test failures. I'll test some more.

@juliantaylor
Copy link
Contributor

ok got the 2.7 sdk to compile numpy, we should probably see if we can make this easier, setting magical environent variables to build numpy is not very ideal (SET DISTUTILS_USE_SDK=1 andSET MSSdk=1)

just using isnan(tmp) seems to work but I still get lots of comparison failed deprecation warnings also when I turn of sse, weird.

@charris
Copy link
Member
charris commented Oct 9, 2015

SSE2 has been available since 2001.

juliantaylor added a commit to juliantaylor/numpy that referenced this issue Oct 9, 2015
msvc2008 32 bit seems to miscompile it otherwise.
closes numpygh-6428
@juliantaylor
Copy link
Contributor

the warnings seem normal with this compiler, should probably be looked at, for now filed a PR with a reasonable fix

@matthew-brett
Copy link
Contributor
matthew-brett commented Oct 9, 2015 via email

@charris
Copy link
Member
charris commented Oct 9, 2015

Looks like two solutions now, thanks guys. The SSE2 solution might be risky. I'll wait until tomorrow for things to sort out, then see to a 1.10.1 release.

@njsmith
Copy link
Member
njsmith commented Oct 10, 2015

Yeah, I think requiring SSE2 is probably a good plan in general, but
probably not a good idea in a bug fix release... IIRC last time this was
discussed then the conclusion was we should do it, but at the same time
take some care and add an import time check to provide a nice error message
if SSE2 isn't available.
On Oct 9, 2015 4:57 PM, "Charles Harris" notifications@github.com wrote:

Looks like two solutions now, thanks guys. The SSE2 solution might be
risky. I'll wait until tomorrow for things to sort out, then see to a
1.10.1 release.


Reply to this email directly or view it on GitHub
#6428 (comment).

@cgohlke
Copy link
Contributor Author
cgohlke commented Oct 10, 2015

With #6438 the following test errors remain (#6440 fixes these too):

======================================================================
ERROR: test_multiarray.TestIO.test_roundtrip_binary_str
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "X:\Python27\lib\site-packages\numpy\core\tests\test_multiarray.py", line 3264, in test_roundtrip_binary_str
    assert_array_equal(y, self.x.flat)
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 782, in assert_array_equal
    verbose=verbose, header='Arrays are not equal')
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 674, in assert_array_compare
    chk_same_position(x == +inf, y == +inf, hasval='+inf')
DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.

======================================================================
ERROR: test_multiarray.TestIO.test_roundtrip_file
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "X:\Python27\lib\site-packages\numpy\core\tests\test_multiarray.py", line 3254, in test_roundtrip_file
    assert_array_equal(y, self.x.flat)
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 782, in assert_array_equal
    verbose=verbose, header='Arrays are not equal')
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 674, in assert_array_compare
    chk_same_position(x == +inf, y == +inf, hasval='+inf')
DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.

======================================================================
ERROR: test_multiarray.TestIO.test_roundtrip_filename
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "X:\Python27\lib\site-packages\numpy\core\tests\test_multiarray.py", line 3259, in test_roundtrip_filename
    assert_array_equal(y, self.x.flat)
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 782, in assert_array_equal
    verbose=verbose, header='Arrays are not equal')
  File "X:\Python27\lib\site-packages\numpy\testing\utils.py", line 674, in assert_array_compare
    chk_same_position(x == +inf, y == +inf, hasval='+inf')
DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.

======================================================================
ERROR: test_numeric.TestIsclose.test_equal_nan
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "X:\Python27\lib\site-packages\numpy\core\tests\test_numeric.py", line 1560, in test_equal_nan
    assert_array_equal(np.isclose(np.nan, np.nan, equal_nan=True), [True])
  File "X:\Python27\lib\site-packages\numpy\core\numeric.py", line 2366, in isclose
    cond[~finite] = (x[~finite] == y[~finite])
DeprecationWarning: elementwise == comparison failed; this will raise an error in t
9E88
he future.

======================================================================
ERROR: Failure: DeprecationWarning (elementwise == comparison failed; this will raise an error in the future.)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\nose\loader.py", line 284, in generate
    for test in g():
  File "X:\Python27\lib\site-packages\numpy\core\tests\test_numeric.py", line 1529, in test_ip_isclose
    yield (assert_array_equal, np.isclose(x, y), result)
  File "X:\Python27\lib\site-packages\numpy\core\numeric.py", line 2366, in isclose
    cond[~finite] = (x[~finite] == y[~finite])
DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.

======================================================================
ERROR: test_numeric.TestIsclose.test_ip_isclose_allclose([1e-08, 1, 1000020.0000000099], [0, nan, 1000000.0])
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "X:\Python27\lib\site-packages\numpy\core\tests\test_numeric.py", line 1540, in tst_isclose_allclose
    assert_array_equal(np.isclose(x, y).all(), np.allclose(x, y), msg % (x, y))
  File "X:\Python27\lib\site-packages\numpy\core\numeric.py", line 2366, in isclose
    cond[~finite] = (x[~finite] == y[~finite])
DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.

======================================================================
ERROR: test_user_missing_values (test_io.TestFromTxt)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\numpy\lib\tests\test_io.py", line 1343, in test_user_missing_values
    **basekwargs)
  File "X:\Python27\lib\site-packages\numpy\lib\npyio.py", line 1922, in mafromtxt
    return genfromtxt(fname, **kwargs)
  File "X:\Python27\lib\site-packages\numpy\lib\npyio.py", line 1881, in genfromtxt
    outputmask[name] |= (output[name] == mval)
DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.

======================================================================
ERROR: test_withmissing (test_io.TestFromTxt)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "X:\Python27\lib\site-packages\numpy\lib\tests\test_io.py", line 1330, in test_withmissing
    test = np.mafromtxt(data, **kwargs)
  File "X:\Python27\lib\site-packages\numpy\lib\npyio.py", line 1922, in mafromtxt
    return genfromtxt(fname, **kwargs)
  File "X:\Python27\lib\site-packages\numpy\lib\npyio.py", line 1881, in genfromtxt
    outputmask[name] |= (output[name] == mval)
DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.

----------------------------------------------------------------------
Ran 5557 tests in 41.246s

FAILED (KNOWNFAIL=7, SKIP=10, errors=8)

@charris
Copy link
Member
charris commented Oct 10, 2015

Hmm, that is strange set of errors to be fixed by SSE2.

@charris
Copy link
Member
charris commented Oct 10, 2015

Maybe inf related?

@charris
Copy link
Member
charris commented Oct 10, 2015

I'm thinking the SSE2 solution for msvc9 is the way to go. My reasoning is

  • mingw32 is available for windows 32 bit
  • we supply binaries for the common cases (Python 2.7, 3.2)
  • there are other places to get binaries for windows, Enthought, Continuum, etc.
  • people doing numerics are more likely to have SSE2 than the .5% of Firefox crashers who don't.
  • code doesn't get messed up to work around a compiler bug

@cgohlke
Copy link
Contributor Author
cgohlke commented Oct 10, 2015

Two things to consider for the SSE2 solution:

  • Does enabling SSE2 work around a compiler bug or work around a bug in the code?
  • Enabling SSE2 in numpy.distutils will apply not only to building numpy but to all packages using numpy.distutils.

@charris
Copy link
Member
charris commented Oct 10, 2015

@cgohlke If I understand correctly, msvc > 9 works, and gcc seems to have no problems with the same code, so I am going with compiler bug. Your second point is a concern, and perhaps the only way to settle that is to give it a try. @rgommers Maybe we can get Ralf to take a moment out of reviewing SciPy PRs to offer an opinion.

@njsmith
Copy link
Member
njsmith commented Oct 10, 2015

I wonder how many people are even using msvc9 to build numpy... I know that
we, Continuum, @cgohlke aren't, and I'm guessing Enthought is using icc too
(@cournape?). Is anyone using msvc9?
.
Not that I really think we can just drop support, but...
On Oct 10, 2015 11:09 AM, "Charles Harris" notifications@github.com wrote:

@cgohlke https://github.com/cgohlke If I understand correctly, msvc > 9
works, and gcc seems to have no problems with the same code, so I am going
with compiler bug. Your second point is a concern, and perhaps the only way
to settle that is to give it a try. @rgommers
https://github.com/rgommers Maybe we can get Ralf to take a moment out
of reviewing SciPy PRs to offer an opinion.


Reply to this email directly or view it on GitHub
#6428 (comment).

@rgommers
Copy link
Member

If enabling SSE2 on Windows works for numpy itself, then I don't really see a problem with enabling it for other packages using numpy.distutils.

I'd still prefer a nice warning for those few users that are still without SSE2, but each time we discuss this 6-12 months have passed so my preference becomes less and less relevant.... maybe the time has come to just pull the trigger.

@juliantaylor
Copy link
Contributor

note that numpy used sse2 when built with msvc since 1.8, just not for every part of the code

@njsmith
Copy link
Member
njsmith commented Oct 11, 2015

Another interesting note on SSE2: apparently Python 3.5 on Windows requires
SSE2. See
https://mail.python.org/pipermail/distutils-sig/2015-October/027154.html

On Sat, Oct 10, 2015 at 11:45 AM, Julian Taylor notifications@github.com
wrote:

note that numpy used sse2 when built with msvc since 1.8


Reply to this email directly or view it on GitHub
#6428 (comment).

Nathaniel J. Smith -- http://vorpus.org

@cournape
Copy link
Member

@njsmith we use msvc 9 to build every package on 2.7.

@njsmith
Copy link
Member
njsmith commented Oct 11, 2015

@cournape: are you ok with enabling SSE2 in 2.7 builds?
On Oct 11, 2015 7:09 AM, "Charles Harris" notifications@github.com wrote:

Closed #6428 #6428 via #6438
#6438.


Reply to this email directly or view it on GitHub
#6428 (comment).

@njsmith
Copy link
Member
njsmith commented Oct 11, 2015

Re-opening because I'm not sure #6438 is still intended as the final fix for this so someone who understands what's going on better should probably close it by hand instead of trusting the auto close mechanism.

@njsmith njsmith reopened this Oct 11, 2015
charris pushed a commit to charris/numpy that referenced this issue Oct 11, 2015
msvc2008 32 bit seems to miscompile it otherwise.
closes numpygh-6428
@cournape
Copy link
Member

I will take a look tomorrow to see if we can get some idea of the proportion of our customers w/ a CPU that is not SSE2 enabled.

@njsmith
Copy link
Member
njsmith commented Oct 11, 2015

@cournape: note also #6428 (comment)

@matthew-brett
Copy link
Contributor

Also my comment up this thread : #6428 (comment) - Firefox crash reports : SSE2 == 99.5%

Steam hardware survey : SSE2 == 99.99%

@juliantaylor
Copy link
Contributor

unless you are not shipping numpy 1.8 yet its irrelevant, its already required since 1.8 with msvc builds

@cgohlke
Copy link
Contributor Author
cgohlke commented Oct 12, 2015

Numpy-1.10.1 is passing all tests. Closing.

@cgohlke cgohlke closed this as completed Oct 12, 2015
@charris
Copy link
Member
charris commented Oct 12, 2015

Thanks to @cgohlke and @JulianTay for getting this fixed.

jaimefrio pushed a commit to jaimefrio/numpy that referenced this issue Mar 22, 2016
msvc2008 32 bit seems to miscompile it otherwise.
closes numpygh-6428
@dbush-vonage
Copy link

The !(tmp == 0.) issue is being discussed here

@native-api
Copy link
native-api commented Jul 8, 2016

@charris could you please comment on comment-146975795 at http://stackoverflow.com/q/38270589/648265 (or wherever)? Looks like what is says is not as true and common knowledge as you make it sound to be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants
0