pts
pts

Reputation: 87221

Detect which function to call based on argument type in OpenWatcom C language

I have 2 implementations of the same function based on the pointer size in the argument:

/* Writes a $-delimited string to stdout. */   
static inline void _printmsgx(const char *msg);
#pragma aux _printmsgx = "mov ah, 9" "int 0x21" parm [ dx ] modify [ ah ];

/* Writes a $-delimited string (with far pointer) to stdout. */
static inline void _printmsgx_far(const char far *msg);
#pragma aux _printmsgx_far = "mov ah, 9" "push ds" "push es" "pop ds" "int 0x21" "pop ds" \
    parm [ es dx ] modify [ ah ];

I'd like to select automatically which one to call, so I've written a macro:

#define _printmsgx_best(msg) ((sizeof((msg)+0) == sizeof(const char*)) ? \
    _printmsgx(msg) : _printmsgx_far(msg))

However, if this is called with a far pointer, wcc gives a warning for the branch not called:

foo.c(17): Warning! W112: Parameter 1: Pointer truncated
foo.c(17): Note! N2003: source conversion type is 'char __far const *'
foo.c(17): Note! N2004: target conversion type is 'char const *'

I also tried C11 _Generic, but it doesn't seem top be supported by wcc:

#define _printmsgx_best(msg) _Generic((msg), \
    const char far*: _printmsgx_far(msg), const char*: _printmsgx(msg))

I get this warning and then errors:

foo.c(17): Warning! W131: No prototype found for function '_Generic'

How do I make it work without warnings, in C (not C++), with wcc in Open Watcom V2, in the small memory model (-ms)?

Upvotes: 1

Views: 90

Answers (1)

pts
pts

Reputation: 87221

Inspired by the comment by @Raymond Chen:

#define _printmsgx_best(msg) ((sizeof((msg)+0) == sizeof(const char*)) ? \
    _printmsgx((const char*)(size_t)msg) : _printmsgx_far(msg))

This does enough type checking, because if msg has some incompatible type, it will be reported for _printmsgx_far(msg), even if that branch is not taken.

Upvotes: 0

Related Questions