From: Bruno Luong on
This post concerns MEX programming on 64 bit platform

I have this piece of MEX code. I declare a variable as mwSize. It's clearly can take a negative value, however in 64-bit platform I'm unable to make a test if the value is negative as showed below. That's very odd.

My configuration is Matlab 2010A and MSVC 2008.

It works fine when compile without "-largeArrayDims" option (so no problem with 32 platform).

Any comments?

Bruno

%%%%%%%%%%%%
#include "mex.h"
#include "matrix.h"

#define COUNT prhs[0]

/* Gateway of testmwSizeCmp */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {

mwSize count;

count = (mwSize)(*(mxGetPr(COUNT)));

/* count<0 return 0 if compiled with -largeArrayDims option */
mexPrintf("count = %d, count<0=%d\n", count, count<0);
if (count<0)
mexPrintf("Testif OK\n");
else
mexPrintf("Testif failed\n");

return;

} /* testmwSizeCmp */

% Command line checking
>> mex -largeArrayDims testmwSizeCmp.c
>> testmwSizeCmp(-1)
count = -1, count<0=0
Testif failed
>>
From: James Tursa on
"Bruno Luong" <b.luong(a)fogale.findmycountry> wrote in message <hstlhg$71d$1(a)fred.mathworks.com>...
> This post concerns MEX programming on 64 bit platform
>
> I have this piece of MEX code. I declare a variable as mwSize. It's clearly can take a negative value, however in 64-bit platform I'm unable to make a test if the value is negative as showed below. That's very odd.
>
> My configuration is Matlab 2010A and MSVC 2008.
>
> It works fine when compile without "-largeArrayDims" option (so no problem with 32 platform).
>
> Any comments?
>
> Bruno
>
> %%%%%%%%%%%%
> #include "mex.h"
> #include "matrix.h"
>
> #define COUNT prhs[0]
>
> /* Gateway of testmwSizeCmp */
> void mexFunction(int nlhs, mxArray *plhs[],
> int nrhs, const mxArray *prhs[]) {
>
> mwSize count;
>
> count = (mwSize)(*(mxGetPr(COUNT)));
>
> /* count<0 return 0 if compiled with -largeArrayDims option */
> mexPrintf("count = %d, count<0=%d\n", count, count<0);
> if (count<0)
> mexPrintf("Testif OK\n");
> else
> mexPrintf("Testif failed\n");
>
> return;
>
> } /* testmwSizeCmp */
>
> % Command line checking
> >> mex -largeArrayDims testmwSizeCmp.c
> >> testmwSizeCmp(-1)
> count = -1, count<0=0
> Testif failed
> >>

I don't have a 64-bit system, but I believe mwSize is an unsigned integer type for your setup. e.g., take this program:

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mwSize count;
count = -1;
if (count<0) {
mexPrintf("mwSize is signed\n");
} else {
mexPrintf("mwSize is unsigned\n");
}
}

Here are the results on 32-bit WinXP R2008b:

>> mex mwSizeCheck.c
>> mwSizeCheck
mwSize is signed
>> mex mwSizeCheck.c -largeArrayDims
>> mwSizeCheck
mwSize is unsigned

James Tursa
From: Bruno Luong on
"James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <hsubm4$ph5$1(a)fred.mathworks.com>...
>
> I don't have a 64-bit system, but I believe mwSize is an unsigned integer type for your setup.

Thanks James. That's likely the explanation. Just wonder why they change signed to unsigned. It's very dangerous move.

Bruno
From: James Tursa on
"Bruno Luong" <b.luong(a)fogale.findmycountry> wrote in message <hsudg9$qpj$1(a)fred.mathworks.com>...
> "James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <hsubm4$ph5$1(a)fred.mathworks.com>...
> >
> > I don't have a 64-bit system, but I believe mwSize is an unsigned integer type for your setup.
>
> Thanks James. That's likely the explanation. Just wonder why they change signed to unsigned. It's very dangerous move.
>
> Bruno

In earlier versions of MATLAB they used int for the interface. Then at some point they made the change to the mwSize typedef to accommodate the larger array sizes, and at that point you introduce the signed/unsigned difference. In retrospect they probably should have used size_t from the very beginning and then when the switch to mwSize was made they both would have been unsigned. That being said, I don't see why going to an unsigned type is dangerous though. There shouldn't be any code out there that uses an mwSize variable for negative values. I think the programmer shouldn't ever be doing anything in the code that relies on mwSize being signed or unsigned. e.g., you should never subtract two mwSize variables like this:

mwSize a, b;
:
if( (a - b) < 0 ) etc.

because you don't know if the (a - b) calculation will be performed as signed or unsigned and the result will critically depend on this. You need to recode it as:

mwSize a, b;
:
if( a < b ) etc.


James Tursa
From: Jan Simon on
Dear Bruno!

You can use mwSignedIndex for signed pointer operations. This is ptrdiff_t for the largeArrayDims mode, and as far as I can see, this is equal to ssize_t.

After digging in the file tmwtypes.h it looks like the maximum values for 64 bit addressing for mwSize and mwIndex are 2^48, while mwSignedIndex has a valid range of +-2^48.
For the old 32 bit addressing the maximum value of mwSize is 2^31 (MWSIZE_MAX) - so 1 bit of the [int] is unused. And mwSignedIndex has a range of +-2^31 (MWSINDEX_MIN and MWSINDEX_MAX) - as expected for [int].

Kind regards, Jan