writing usb drivers under 8.x
Jim Bryant
kc5vdj.freebsd at gmail.com
Mon Aug 30 02:26:46 UTC 2010
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 <stdio.h>
#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", at 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", at 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
> <stdio.h>, 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 <ctype.h> 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 <stdio.h>
>>
>> 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", at 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", at 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 at pluto.rain.com wrote:
>>> Jim Bryant <kc5vdj.freebsd at gmail.com> 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.
>>>
>>>
>>
>
More information about the freebsd-usb
mailing list