# XS Constants peculiarity

Dirk Koopman djk at tobit.co.uk
Thu Oct 28 16:03:34 BST 2010

```On 28/10/10 13:35, Abigail wrote:
> On Thu, Oct 28, 2010 at 11:03:14AM +0100, Dirk Koopman wrote:
>> A few years ago I put together an XS interface to an internal program
>> writing system that a company I work for occasionally uses.
>>
>> The constants are standard ones that XS generates (i.e. integers) and
>>
>>   perl -e 'use FF;  printf "0x%x\n", \$_ for (LOCK, RK, RK | LOCK, RK +
>> LOCK)'
>>
>> yields:
>>
>> 0x100000
>> 0x4
>> 0x100004
>> 0x4
>>
>> Why would RK + LOCK give a different result to RK | LOCK?
>
>
> My guess, RK is seen as a function taking a list, making RK + LOCK to be
> equivalent to RK(+LOCK).
>
> Make sure RK is declared to not take arguments (empty prototype).
>

h2xs (IIRC) generated a file of constants called c-const.inc. In there
it contains a load of switch statements including:

static int
constant_2 (pTHX_ const char *name, IV *iv_return) {
/* When generated this function returned values for the list of names
given
here.  However, subsequent manual editing may have added or
removed some.
AD BS CD CF CL CR CU DC DE DR DU EN ES F1 F2 F3 F4 F5 F6 F7 F8 F9
FL GS GU
HM IN IR LT OF PD PG PK PL PU RD RF RG RK RL RM RN RP SO SU TB WC
WR */
/* Offset 1 gives the best switch position.  */
switch (name[1]) {

...

case 'K':
if (name[0] == 'P') {
#ifdef PK
*iv_return = PK;
return PERL_constant_ISIV;
#else
return PERL_constant_NOTDEF;
#endif
}
if (name[0] == 'R') {
#ifdef RK
*iv_return = RK;
return PERL_constant_ISIV;
#else
return PERL_constant_NOTDEF;
#endif
}
break;

and

static int
constant_6 (pTHX_ const char *name, IV *iv_return) {
/* When generated this function returned values for the list of names
given
here.  However, subsequent manual editing may have added or
removed some.
CALCIF CALCLB CALCRB CRMODE DUPCHK FAUDIT FFCALC FFCVTL FFFILE FFISAM
FFLIST FLDCHR GRTHAN MAXFKL MXPRNT NOLOCK NOSAVE TBLANK TERMSZ
UNLOCK */
/* Offset 4 gives the best switch position.  */
switch (name[4]) {

...

case 'L':
if (memEQ(name, "OCK", 3)) {
/*                L         */
#ifdef LOCK
*iv_return = LOCK;
return PERL_constant_ISIV;
#else
return PERL_constant_NOTDEF;
#endif
}
break;

This is not my stuff, this is generated from the original header file(s).

Prototypes? Functions??

Dirk
```