From owner-freebsd-usb@FreeBSD.ORG Mon Aug 30 02:26:46 2010 Return-Path: Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 637081065674 for ; Mon, 30 Aug 2010 02:26:46 +0000 (UTC) (envelope-from kc5vdj.freebsd@gmail.com) Received: from mail-iw0-f182.google.com (mail-iw0-f182.google.com [209.85.214.182]) by mx1.freebsd.org (Postfix) with ESMTP id 22B928FC14 for ; Mon, 30 Aug 2010 02:26:45 +0000 (UTC) Received: by iwn36 with SMTP id 36so5104446iwn.13 for ; Sun, 29 Aug 2010 19:26:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:cc:subject:references:in-reply-to :content-type:content-transfer-encoding; bh=TtaExmJoLR6Dax8lSgEzeNgWRTwjTns6xK7y8sFE+J0=; b=B6ZzlWDyC63sobYDRDpA3bXXVmpj9q3VgxsvklLgRAncBnZLp0PHUlTI6IuJkLEnyG JYqDxZC5pu2emJIxxX+Cwa2zHlviHm4XRwOLQ/pDwwELz8uIDOAKmuUDcZEKs1d3E5uw Co5JRz5F7DXttJ8LusDYpr6pM37IV69pzGz3w= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; b=g0oqtDhmQXf95wuYkUrScrXfqtlmtgXpvBekd3yIKvuSuhLcvp4n5nv+egedq3FxqZ xjHmDlbrZJQsxVYAYxkETBnqWfgNNrKPzpuqggkPR2phGquKMp+4ol7eklc2CC4M2QTR jR14OBc4qyjQhhgo1+xZFEtOoNtusJJf3XMa8= Received: by 10.231.58.198 with SMTP id i6mr4602152ibh.43.1283135205183; Sun, 29 Aug 2010 19:26:45 -0700 (PDT) Received: from orb.electron-tube.net (71-217-215-181.cdrr.qwest.net [71.217.215.181]) by mx.google.com with ESMTPS id e8sm6873396ibb.20.2010.08.29.19.26.44 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 29 Aug 2010 19:26:44 -0700 (PDT) Message-ID: <4C7B16E3.8020808@gmail.com> Date: Sun, 29 Aug 2010 21:26:43 -0500 From: Jim Bryant User-Agent: Thunderbird 2.0.0.24 (X11/20100731) MIME-Version: 1.0 To: perryh@pluto.rain.com References: <4C76AB76.4070806@gmail.com> <201008270856.43512.hselasky@c2i.net> <4C777D12.3040900@gmail.com> <201008271053.27731.hselasky@c2i.net> <4C78B0F4.4020002@gmail.com> <4c799393.wU/d2YpTieErDrD7%perryh@pluto.rain.com> <4C7B1139.4050106@gmail.com> <4C7B1510.1000601@gmail.com> In-Reply-To: <4C7B1510.1000601@gmail.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-usb@freebsd.org Subject: Re: writing usb drivers under 8.x X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Aug 2010 02:26:46 -0000 but then gnu does it's own thing too. my point stands though. any actual evaluation of thirtytwok into something OTHER THAN (1<<15) in the actual emitted code is IMPLEMENTATION-SPECIFIC. in the case if gnu, you do appear to be right though, in disregard to K&R. one could also argue that my return(0) is implementation-specific, as exit(0) would be proper by the numbers. my point still stands, that although it may be cute to have (1<<15) in the define, it is not good practice. 9:21:33pm orb(13): cat bs4.c #include #define thirtytwok (1<<15) int main(void) { int toshiftornottoshift = thirtytwok; printf("%d\n", toshiftornottoshift); return(0); } 9:21:39pm orb(14): cc -S -O2 -o bs4.s bs4.c 9:21:56pm orb(15): cat bs4.s .file "bs4.c" .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "%d\n" .text .p2align 4,,15 .globl main .type main, @function main: .LFB3: subq $8, %rsp .LCFI0: movl $32768, %esi movl $.LC0, %edi xorl %eax, %eax call printf xorl %eax, %eax addq $8, %rsp ret .LFE3: .size main, .-main .section .eh_frame,"a",@progbits .Lframe1: .long .LECIE1-.LSCIE1 .LSCIE1: .long 0x0 .byte 0x1 .string "zR" .uleb128 0x1 .sleb128 -8 .byte 0x10 .uleb128 0x1 .byte 0x3 .byte 0xc .uleb128 0x7 .uleb128 0x8 .byte 0x90 .uleb128 0x1 .align 8 .LECIE1: .LSFDE1: .long .LEFDE1-.LASFDE1 .LASFDE1: .long .LASFDE1-.Lframe1 .long .LFB3 .long .LFE3-.LFB3 .uleb128 0x0 .byte 0x4 .long .LCFI0-.LFB3 .byte 0xe .uleb128 0x10 .align 8 .LEFDE1: .ident "GCC: (GNU) 4.2.1 20070719 [FreeBSD]" 9:22:00pm orb(16): Jim Bryant wrote: > well, i can't speak for K&R 1978, as i can't currently find my copy, > but, for a quick brush up, you might want to read pages 80 and 81 from > K&R 2nd Ed. 1988. > > your idea that the preprocessor will evaluate > > #define thirtytwok (1<<15) > > into 0x8000 > > at compile time is totally incorrect, and in fact wouldn't be in > compliance with standards. i have iso and fips handy, care for quotes? > > microsoft used to do compile-time eval of preprocessor statements > instead of substitution, but that was implementation-specific and > non-standard. > > From K&R, 2nd Ed. pp80-81 (1988): > > 4.11.2 Macro Substitution > > A definition has the form > > #define name replacement text > > It calls for a macro substitution of the simplest kind - subsequent > occurrences of the token > name will be replaced by the replacement text. The name in a #define > has the same form as a > variable name; the replacement text is arbitrary. Normally the > replacement text is the rest of > the line, but a long definition may be continued onto several lines by > placing a \ at the end of > each line to be continued. The scope of a name defined with #define is > from its point of > definition to the end of the source file being compiled. A definition > may use previous > definitions. Substitutions are made only for tokens, and do not take > place within quoted > strings. For example, if YES is a defined name, there would be no > substitution in > printf("YES") or in YESMAN. > > Any name may be defined with any replacement text. For example > > #define forever for (;;) /* infinite loop */ > > defines a new word, forever, for an infinite loop. > > It is also possible to define macros with arguments, so the > replacement text can be different > for different calls of the macro. As an example, define a macro called > max: > > #define max(A, B) ((A) > (B) ? (A) : (B)) > > Although it looks like a function call, a use of max expands into > in-line code. Each occurrence > of a formal parameter (here A or B) will be replaced by the > corresponding actual argument. > > Thus the line > > x = max(p+q, r+s); > > will be replaced by the line > > x = ((p+q) > (r+s) ? (p+q) : (r+s)); > > So long as the arguments are treated consistently, this macro will > serve for any data type; > there is no need for different kinds of max for different data types, > as there would be with > functions. > > 81 > > If you examine the expansion of max, you will notice some pitfalls. > The expressions are > evaluated twice; this is bad if they involve side effects like > increment operators or input and > output. For instance > > max(i++, j++) /* WRONG */ > > will increment the larger twice. Some care also has to be taken with > parentheses to make sure > the order of evaluation is preserved; consider what happens when the > macro > > #define square(x) x * x /* WRONG */ > > is invoked as square(z+1). > > Nonetheless, macros are valuable. One practical example comes from > , in which > getchar and putchar are often defined as macros to avoid the run-time > overhead of a > function call per character processed. The functions in are > also usually > implemented as macros. > > Names may be undefined with #undef, usually to ensure that a routine > is really a function, not > a macro: > > #undef getchar > int getchar(void) { ... } > > Formal parameters are not replaced within quoted strings. If, however, > a parameter name is > preceded by a # in the replacement text, the combination will be > expanded into a quoted string > with the parameter replaced by the actual argument. This can be > combined with string > concatenation to make, for example, a debugging print macro: > > #define dprint(expr) printf(#expr " = %g\n", expr) > > When this is invoked, as in > > dprint(x/y) > > the macro is expanded into > > printf("x/y" " = &g\n", x/y); > > and the strings are concatenated, so the effect is > > printf("x/y = &g\n", x/y); > > Within the actual argument, each " is replaced by \" and each \ by \\, > so the result is a legal > string constant. > > The preprocessor operator ## provides a way to concatenate actual > arguments during macro > expansion. If a parameter in the replacement text is adjacent to a ##, > the parameter is replaced > by the actual argument, the ## and surrounding white space are > removed, and the result is rescanned. > > For example, the macro paste concatenates its two arguments: > > #define paste(front, back) front ## back > > so paste(name, 1) creates the token name1. > > The rules for nested uses of ## are arcane; further details may be > found in Appendix A. > Exercise 4-14. Define a macro swap(t,x,y) that interchanges two > arguments of type t. > (Block structure will help.) > > Jim Bryant wrote: >> ummmm.. you were saying??? >> >> 8:58:44pm orb(19): cat bs3.c >> #include >> >> int main(void) >> { >> int toshiftornottoshift = 0x8000; >> >> printf("%d\n", toshiftornottoshift); >> >> return(0); >> } >> 8:58:48pm orb(20): cc -S -O2 -o bs3.s bs3.c >> 8:58:53pm orb(21): cat bs3.s >> .file "bs3.c" >> .section .rodata.str1.1,"aMS",@progbits,1 >> .LC0: >> .string "%d\n" >> .text >> .p2align 4,,15 >> .globl main >> .type main, @function >> main: >> .LFB3: >> subq $8, %rsp >> .LCFI0: >> /* >> * this doesn't look like the compiler generates a shift to me. >> */ >> movl $32768, %esi >> movl $.LC0, %edi >> xorl %eax, %eax >> call printf >> xorl %eax, %eax >> addq $8, %rsp >> ret >> .LFE3: >> .size main, .-main >> .section .eh_frame,"a",@progbits >> .Lframe1: >> .long .LECIE1-.LSCIE1 >> .LSCIE1: >> .long 0x0 >> .byte 0x1 >> .string "zR" >> .uleb128 0x1 >> .sleb128 -8 >> .byte 0x10 >> .uleb128 0x1 >> .byte 0x3 >> .byte 0xc >> .uleb128 0x7 >> .uleb128 0x8 >> .byte 0x90 >> .uleb128 0x1 >> .align 8 >> .LECIE1: >> .LSFDE1: >> .long .LEFDE1-.LASFDE1 >> .LASFDE1: >> .long .LASFDE1-.Lframe1 >> .long .LFB3 >> .long .LFE3-.LFB3 >> .uleb128 0x0 >> .byte 0x4 >> .long .LCFI0-.LFB3 >> .byte 0xe >> .uleb128 0x10 >> .align 8 >> .LEFDE1: >> .ident "GCC: (GNU) 4.2.1 20070719 [FreeBSD]" >> >> perryh@pluto.rain.com wrote: >>> Jim Bryant wrote: >>> >>> >>>> what kind of idiot defines a constant assignment for a 32k buffer >>>> as a 15 bit left shift of 1? >>>> >>>> clever, yes. but in production, stupid. >>>> >>>> a constant should be just that, a constant, and thus require no >>>> computation at runtime. >>>> >>> >>> Er, did you bother to look at the generated code before spouting off? >>> Most compilers, even as far back as K&R 1st edition, will compute >>> constant expressions like that at compile time. >>> >>> >> >