On at least some systems, the Stata Plugin Interface uses 32-bit signed integers in places where it should use 64-bit integers. For instance, stplugin.h (see https://www.stata.com/plugins/#sect8) defines ST_int as int. Given that Stata observations can range from 0 to 20 billion (though c(max_N_theory) shows north of a trillion?) it seems the plugin interface should explicitly use 64-bit integers. Otherwise you get overflow errors on some systems:
And then (on Stata 15/MP for unix):
The second run gives an error not just because SF_in2() overflowed, but because ST_vstore does not seem to accept values past 2^31-1 (we can see that the last value of x is left unchanged, but not the value where obs = largest signed integer). I've tried changing every "int" in stplugin.h to "int64_t" but it hasn't helped, so I think the issue might not just be with stplugin.h, but with the underlying types as well.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include "stplugin.h"
#define BUF_MAX 4096
void sf_printf (const char *fmt, ...);
STDLL stata_call(int argc, char *argv[])
{
ST_retcode rc;
rc = SF_vstore(1, SF_in2(), (ST_double) 1.0);
sf_printf("status 1 = %d \n", rc);
if ( rc ) {
rc = SF_vstore(1, INT32_MAX, (ST_double) 2.0);
sf_printf("status 2 = %d \n", rc);
rc = SF_vstore(1, 2165097182, (ST_double) 3.0);
sf_printf("status 3 = %d \n", rc);
sf_printf("sizeof(ST_int) = %d\n", sizeof(ST_int));
sf_printf("SF_in2() = %d \n", SF_in2());
}
return (rc);
}
void sf_printf (const char *fmt, ...)
{
va_list args;
va_start (args, fmt);
char buf[BUF_MAX];
vsprintf (buf, fmt, args);
SF_display (buf);
va_end (args);
}
Code:
. !gcc -Wall -shared -DSYSTEM=OPUNIX -fPIC stplugin.c test.c -o test.plugin
. program test, plugin using("test.plugin")
. set obs 3
number of observations (_N) was 0, now 3
. gen x = .
(3 missing values generated)
. plugin call test x
status 1 = 0
. l
+---+
| x |
|---|
1. | . |
2. | . |
3. | 1 |
+---+
.
. set obs 2165097182
number of observations (_N) was 3, now 2,165,097,182
. plugin call test x
status 1 = 498
status 2 = 0
status 3 = 498
sizeof(ST_int) = 4
SF_in2() = -2129870114
r(498);
. l in `=2^31 - 1'
+---+
| x |
|---|
2147483647. | 2 |
+---+
. l in `=_N'
+---+
| x |
|---|
2165097182. | . |
+---+

Comment