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