www.delorie.com/djgpp/bugs/show.cgi   search  
Bug 000063

When Created: 02/29/1996 12:07:09
Against DJGPP version: 2.00
By whom: olly@mantis.co.uk
Abstract: #define bdosptr in dos.h could cause problems
The line:

#define bdosptr(a, b, c) bdos(a, (unsigned) b, c)

could be problematic if an unbracketed expression is given for b,
as a cast binds tighter than most binary operators.

For example, consider:

char *p;
int i;
bdosptr( x, i+p, y );

Solution added: 02/29/1996 12:08:25
By whom: olly@mantis.co.uk
Here's a diff -C3 patch for dos.h which should fix this problem:

*** DOS.H~	Sat Nov 18 22:59:34 1995
--- DOS.H	Thu Feb 29 16:42:14 1996
***************
*** 136,142 ****
  int bdos(int func, unsigned dx, unsigned al);
  int bdosptr(int func, void *dx, unsigned al);
  
! #define bdosptr(a, b, c) bdos(a, (unsigned) b, c)
  #define intdos(a, b) int86(0x21, a, b)
  #define intdosx(a, b, c) int86x(0x21, a, b, c)
  
--- 136,142 ----
  int bdos(int func, unsigned dx, unsigned al);
  int bdosptr(int func, void *dx, unsigned al);
  
! #define bdosptr(a, b, c) bdos(a, (unsigned)(b), c)
  #define intdos(a, b) int86(0x21, a, b)
  #define intdosx(a, b, c) int86x(0x21, a, b, c)

Note added: 03/02/1996 14:38:17
By whom: terra@diku.dk (Morten Welinder)
All macro parameters should have parentheses.  Unexpected things
can happen if they don't.

Note added: 03/04/1996 14:41:55
By whom: olly@mantis.co.uk
I believe it's safe to write things like:

#define foo(a,b) bar(a,b)

The only thing in the parameter I can think of which could cause a problem
would be an unbracketted comma, and that would be treated as a parameter
separator by the macro expansion.

For most other cases, I agree brackets are likely to be vital to get the
desired behaviour in all cases.

Olly

Note added: 03/05/1996 11:25:11
By whom: terra@diku.dk (Morten Welinder)
Parentheses everywhere!  For a bizarre example, try this perfectly
valid C program.  Further fun can be had with unbalanced parenthesis
and such.

void bar (int a, int b) { printf ("%d %d", a, b); }
#define foo(a,b) bar(a,b)
#define baz +2:2,3
void main () { foo(1?1,baz); }

The following is not a valid C program, however, and this is what
you would like the C compiler to tell you.

void bar (int a, int b) { printf ("%d %d", a, b); }
#define foo(a,b) bar((a),(b))
#define baz +2:2,3
void main () { foo(1?1,baz); }

Note added: 03/05/1996 11:50:49
By whom: olly@mantis.co.uk
Inspired by your unbalanced parenthesis comment, I spotted you can defeat the
bracketted macro arguments like so:

void bar (int a, int b) { printf ("%d %d", a, b); }
#define foo(a,b) bar((a),(b))
#define foz (0
#define baz 0)),(3
void main () { foo(foz,baz); }

Fixed in version 2.01 on 06/12/1996 23:58:26
By whom: dj@delorie.com



  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2010   by DJ Delorie     Updated Jul 2010