This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to use extern sbit declare?

I declare a variable unsigned char bdata Kde in a.c.

[in file a.c]

unsigned char bdata Kde;

Than I want to use the variable inb.c.
[in file b.c]
#include <stdio.h>
.....
extern unsigned char bdata Kde;
sbit testbit=Kde^1;
void main(void)
{......}

:error C141:.......a.c:syntax error near 'sbit'

why?

Parents
  • Andrew,

    Thanks, the preprocessor listing could have exposed the problem sooner had I known about it.

    As far as being unable to turn off the optimizer, this seems like an undesirable idea. Why would the compiler writers have a problem with an option of NOT optimizing? I'm sure it would have saved me time earlier today.

    Robert

Reply
  • Andrew,

    Thanks, the preprocessor listing could have exposed the problem sooner had I known about it.

    As far as being unable to turn off the optimizer, this seems like an undesirable idea. Why would the compiler writers have a problem with an option of NOT optimizing? I'm sure it would have saved me time earlier today.

    Robert

Children
  • Turning off the optimizer would not have helped you at all since it did not partake in your "bug". Bypassing the C pre-processor would have yielded an error but you cannot bypass the C pre-processor. A good working knowledge of ISO C would have helped you, however.

  • Mark Odell writes:

    >Turning off the optimizer would not have helped you at all since it did not partake in your "bug".

    Oh, but if I had been able to turn off the optimizer I would have been able to see the constant expression that was being evaluated. This is the point as to why the optimizer was a barrier, and it seems a pointless barrier.

    >A good working knowledge of ISO C would have helped you, however.

    And your point is?...that the way it's been before is the best way?

    Robert

  • Oh, but if I had been able to turn off the optimizer I would have been able to see the constant expression that was being evaluated.

    I'd be pretty surprised to find any compiler that didn't remove the statement:

    0x04;
    Sticking to convention might have proved more helpful, e.g. only MANIFEST_CONSTANTS and ENUMS are uppercase. Doesn't it seem akward to use UPPERCASE variables? I don't even use the upper case sfr definitions in the Keil header files because it is hard too follow.

  • Mark wrote,
    "A good working knowledge of ISO C would have helped you"

    Robert,
    "And your point is?..."

    It's not the compiler's job to pass comment on your style - if you write a valid language construct, the compiler should just generate the corresponding object.

    A statement like

    0x04;
    would be valid 'C'; it does nothing, so the compiler would be perfectly justified in generating no code at all for it. That's not optimisation, that's a straightforward implementation!

    If you want a review of your code, to check if what you wrote is what you meant, you need something like lint and/or peer review (or, if it's all doing your head in, just go to a pier revue!)

  • Mark,

    I tried compiling

     0x04; 

    with the Keil compiler and it is not ignored, it gives a warning:
    ..\MAIN.C(492): warning C275: expression with possibly no effect 
    So that's not something that's removed by optimization at level 0, it's a different topic.

    As I was saying, if I had been able to turn off the optimizer, I would have been able to see whatever it was that the compiler "helpfully" discarded.

    How hard would it be to allow the compiler to finish the job of comparing two constant expressions?

            MOV      A,    #0x04
            XRL      A,    #1
            JNZ      ?C0004
            INC      ERROR_COUNT
    ?0004:
    

    There, we've just compared 0x04 with 1, and if they are equal, we increment ERROR_COUNT.

    I would be surprised if the Keil folks couldn't easily restore this feature. To be sure, I've got other things I'd rather see given priority.

    Robert

  • Mark,

    You wrote,
    >Sticking to convention might have proved more helpful, e.g. only MANIFEST_CONSTANTS and ENUMS are uppercase.

    I'm not sure what you mean by "MANIFEST_CONSTANTS and ENUMS".

    I suppose that this means to use uppercase for the #defines, and lowercase for the sbits. I see now that had this style been in use in the code I was working with this morning, this discussion would not be occurring.

    This may also explain the penchant of C programmers to remove uppercase from everything else, including URLs: fear of the preprocessor! Personally, I have never gotten used to seeing lowercase hex digits, which I first saw done in the C community. I've also noticed that C programmers tend to hack DOS filenames into lowercase. For the bigger picture, I think that the standard remains English.

    Robert

  • Andrew,

    You wrote,
    >It's not the compiler's job to pass comment on your style

    Is it the compiler's job to make my life easier? Of course. And this is a fine distinction between the preprocessor and the compiler, in more general usage the preprocessor IS (a part of) the compiler. I don't need a preprocessor/compiler to ignore the fact that I've used a duplicate label, I need it to optionally give me a warning.

    I looked for a lint utility, and it seems that the C51 lint here on the Keil website is dated 1996. What would you recommend?

    Thanks,
    Robert

  • How hard would it be to allow the compiler to finish the job of comparing two constant expressions?

    That is not a simple question. You see, the ANSI standard from Section 6.6 states the following:

    "A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be."

    So, a C Compiler may evaluate constant expressions at compile-time rather than at run-time. This is the choice of the compiler developer. It is not an optimization. Evaluating constant expressions at compile-time generates tighter code.

    There is no difference at compile-time or at run-time between (int) 1+2 and (int) 3. Both have the same value.

    The Keil compiler DOES evaluate constant expressions at compile-time. I do not know of a good quality compiler that doesn't.

    The Keil compiler DOES NOT generate code with constants evaluated explicitly at run-time. As stated previously, this is not an optimization. It is an allowed and oft-used part of the ANSI specification.

    I'm certain there are plenty of compilers that generate explicit code for each operation (constant or not, unused or not). But, I would not use them for my applications where speed and code size were important.

    Using the assembler listing generated by the compiler is a great way to help you learn the assembly language or even to help you help the compiler generate better code. But, it is not necessarily the best way to help you validate the meaning of your code. That is best done by a utility like PC-LINT (see http://www.keil.com/pclint/ ) which checks the syntax AND SYMANTECS of the program.

    Jon

  • Jon,

    That is very interesting, but I think you are a little bit in denial about what level 0 is doing. It's discarding big chunks of code if it chooses to do so. I don't see that that can be considered anything but optimization.

    Robert

  • "This may also explain the penchant of C programmers to remove uppercase from everything else, including URLs: fear of the preprocessor!"

    Actually, it's more likely to be those with a UNIX background - but then 'C' and UNIX are very closely linked!

    However, some parts of the internet (including some webservers) are case-sensitive (probably mostly the UNIX bits!) - so it's not always safe to fiddle with the capitalisation of a URL, E-Mail address, etc

    "I suppose that this means to use uppercase for the #defines"

    Yes, that is the convention.

    Preprocessor definitions can behave quite differently to 'C' symbols - especially concerning side-effects etc - therefore it is particularly valuable to have your Preprocessor definitions instantly distinguishable, to help avoid the common pitfalls (see any good 'C' book)

  • I'm not sure what you mean by "MANIFEST_CONSTANTS and ENUMS".

    A manifest constant is a #define an enums are enumerated integer constants as you guessed. The uppercase I used here was to indicate that they are conventionally written in uppercase. Variables are not.

    The pre-processor does not remove uppercase and uppercase hex digits have nothing to do with manifest constants or enums. Also, we convert all filenames to lower case since some OS's are case sensitive and since certain OS's don't care it makes it easier to deal with one standard.

    I had a problem with one developer on Linux that could not build my sources which I could build fine on Windows 2000. I had included a file as #include "FooBar.h" but when the file was committed to the CVS repository it ended up as foobar.h. When the Linux compiler attempted a case sensitive match for FooBar.h it could not find it and barfed.

    I have a C coding standard a my website that I invite you to browse to see what makes me tick on this subject. Also, I have some 8051 code samples there too. Enjoy!

    http://www.embeddedfw.com

  • Sorry, but your coding convention document is marked "confidential".

  • Ignore it. It's not confidential, I'm just too lazy to remove it and reprint the PDF. Apologies.

  •    if (count = 5)
       {      
          count = 1;   
       }
       if (1 == 1)
       {      
          count = 2;   
       }
    
    The first "if" statement generates a warning:
    *** WARNING C276 IN LINE 5 OF MAIN.C: constant in condition expression

    The second "if" statement generates no warning.

  • if (count = 5)
    
    is a constant expression as the condition. You are setting count to the value of 5, not comparing it with 5 (= instead of ==)

    The second expression
    if (1 == 1)
    
    can be evaluated and is actually a condition. I would guess that the compiler gets rid of it when optimizing.

    Holger