From owner-freebsd-usb@FreeBSD.ORG Mon Aug 30 02:20:10 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 C7A4A10656E1 for ; Mon, 30 Aug 2010 02:20:10 +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 876AA8FC15 for ; Mon, 30 Aug 2010 02:20:10 +0000 (UTC) Received: by iwn36 with SMTP id 36so5099564iwn.13 for ; Sun, 29 Aug 2010 19:20:09 -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=bhTn0lrOq6K9nUJHRWtvjD2mNralg6o+aN6VJj3czHM=; b=YmIU2IyhpuOfhqbuWdepesTmFSrxPnpXWXWoPjKhzo+soPTezQAVQQjinQhzemMeEa 2bCJXB9qwQQD9/m5j1IB4MjoiDT673bACzO+F5JQLdZlwSm4u3yqT+k/AlAjW9LgJzIy 397MbBEqxv2TZh0f8p55nWGc6+QzV7DpgdOVs= 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=b2/fjnzZGnHmUAASUG85cy5+Q+RCF6Mq0Sr3DwPHtSqUKelvJ3IIpj737e9IgUxuX1 rkNi0fnd2GO+LkCBHiHtIUmvdlsmSAk7KhWCXT7xpO9+o3GCXnYCO1WpywW4W3emkBtf qHX8kKqA10Das7KZdroFIMRlNUvJHiS2p542A= Received: by 10.231.33.67 with SMTP id g3mr4512987ibd.31.1283134738445; Sun, 29 Aug 2010 19:18:58 -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 z6sm5099528ibc.6.2010.08.29.19.18.57 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 29 Aug 2010 19:18:58 -0700 (PDT) Message-ID: <4C7B1510.1000601@gmail.com> Date: Sun, 29 Aug 2010 21:18:56 -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> In-Reply-To: <4C7B1139.4050106@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:20:10 -0000 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. >> >> >