Thread: how to put a check on an extern variable set as flag

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    9

    how to put a check on an extern variable set as flag

    Hello All,

    I am working on a problem, where i have to put a check on an extern variable(flag) and on basis of that check my program could work. The scenario is as following. I have declared an extern variable in ABC.h as "extern uint8 test " and in file ABC.c i am intiallizing it with "extern uint8 test = 1" into a function. In my main file i want to add a check that "if(extern variable int == 1) then perform a function xyz", as my function xyz is dependent on occurence of function in ABC.c.

    But however i am getting an error that two instances of a variable are not allowed or variable is defined two times. Kindly guide me, what other procedure could be adopted, where a check could be implemented to check the gloabl variable defined in another file.

    Best Regards
    Rebelsoul

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Define it some place. Extern it some place else:
    Code:
    extern int x; /* means, 'this is declared elsewhere, but i want to know about it / use it */
    ...
    if ( x == 5 )
        ... do something
    Some other file...
    Code:
    int x = 5;
    You declare it normally in some file, you extern it in all the other ones.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The variable must be declared "extern" in the header file. But do NOT use extern when you initialize it in a .c source file. And you must initialize it in precisely one place, and one place only.

    IOW:

    Code:
    /* header.h */
    
    extern uint8 foo;
    Code:
    /* code.c */
    #include "header.h"
    
    uint8 foo = 1;
    And of course, you NEVER use extern when you reference the variable in code.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    9
    Hello Guys,

    Thank you for the quick reply. But unfortunately still there are warning and errors. I already did the same thing before this post. Declaring a variable extern uint8 Test in my header file "ABC.h" and in my source "ABC.c" i did initialize it as uint8 test =1: as i need this variable as a flag and to check it in my main file. Then i got this warning message
    Warning[Pe177]: variable "test" was declared but never referenced

    and in my main file if i would try to put any check on the variable "test". then i got this error
    Error[Pe029]: expected an expression


    My problem is still ther, so i have a question did anyone ever tried to put a check on a externally intialized flag or a variable in main file. I would be really thankful for the help.

    Best Regards
    Rebelsoul

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by rebelsoul
    Then i got this warning message
    Warning[Pe177]: variable "test" was declared but never referenced
    This warning message is benign and should disappear once you actually use the variable, e.g., in the main function.

    Quote Originally Posted by rebelsoul
    and in my main file if i would try to put any check on the variable "test". then i got this error
    Error[Pe029]: expected an expression
    Show the relevant code. Ideally, post the smallest and simplest program that demonstrates the error.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by rebelsoul View Post
    Hello Guys,

    Thank you for the quick reply. But unfortunately still there are warning and errors. I already did the same thing before this post. Declaring a variable extern uint8 Test in my header file "ABC.h" and in my source "ABC.c" i did initialize it as uint8 test =1: as i need this variable as a flag and to check it in my main file. Then i got this warning message
    Warning[Pe177]: variable "test" was declared but never referenced

    and in my main file if i would try to put any check on the variable "test". then i got this error
    Error[Pe029]: expected an expression
    You aren't giving us a true picture. In one place you say the variable is called "Test", in another you say it's called "test". The variable-declared-but-not-referenced warning should NOT have occurred, if ABC.c was including ABC.h as it should (since the compiler would then know that the variable was intended to be globally visible).

    Can we see some REAL code please?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    9
    Code:
    /*ABC.h */
    
    extern USIGN8 RX_TEST;
    Code:
    /*  ABC.c */
    #include ABC.h
    VOID SYNCMessage(VOID)
    
    {
         USIGN8 frameLen;
         USIGN8 rxBytes;
         //USIGN8 RX_TEST=0;
        
            
        if(SYNC_PIN_IS_HIGH())
        {
           IndSync();
        }
        else
        {
            
            if(RxActive)
            {
                //reset frame buffer
                USIGN8 i = 0;
                for(;i<0x3B;i++)
                {
                    INcomingPacket.frame[i-1] = 0x00;
                }
                
                 USIGN8 RX_TEST=1; //i want to put it here
    
         }
    }
    Code:
    /*main.c*/
    #include ABC.h
    
    //USIGN8 RX_TEST;
    
    VOID main(VOID)
    {
    
       if(RX_TEST==1)
    
          {
              //perform function 
          }
    
    }
    Hello Guys,
    I am pasting a brief codesnipt of what i was trying to do.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    So what is the problem exactly?
    Code:
    #include<stdio.h>
    extern int foo;
    
    int main( void )
    {
        if( foo == 4 )
            printf( "Mmmyep.\n" );
        else
            printf( "Mmmnope.\n" );
    
        return 0;
    }
    That's file 1.
    Code:
    int foo = 4;
    That's file 2.

    gcc -o prog file1.c file2.c -Wall


    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    9
    Hello Quzah,

    To verify your advice, i tried your example snipts. As,instead of header file you had declared extern into source file. I have followed the same style
    Code:
    /* main file */
    extern USIGN8 RX_TEST;
    
    VOID main (VOID)
    
    if(RX_TEST==1)
    {
      perform function a;
    
    }
    else
    {
      perform function b;
    }
    and in my second source file
    Code:
     
    /* ABC.c* /
    VOID SYNCMessage(VOID)
    
    {
         USIGN8 frameLen;
         USIGN8 rxBytes;
         //USIGN8 RX_TEST=0;
        
            
        if(SYNC_PIN_IS_HIGH())
        {
           IndSync();
        }
        else
        {
            
            if(RxActive)
            {
                //reset frame buffer
                USIGN8 i = 0;
                for(;i<0x3B;i++)
                {
                    INcomingPacket.frame[i-1] = 0x00;
                }
                
                 USIGN8 RX_TEST=1; //i want to put it here
    
         }
    }

    and on complilation, i received an error message
    Error[e46]: Undefined external "RX_TEST" referred in main.

    I am using IAR embedded workbench and working on a MSP430 MCU.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    USIGN8 RX_TEST=1;
    That is a LOCAL variable inside the function. You need to declare the variable OUTSIDE of SYNCMessage().

    Is SYNCMessage called from an interrupt or a different thread than main? And are you ever intending to set RX_TEST to something other than 1 (e.g. reset it)?

    If so, you have a race-condition, where the SYNCMessage may just have set it to 1, and you set it to zero.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Mar 2009
    Posts
    9
    i solved it and found the stupidest mistake i made in my program. Thank you guys for the support.

    Best Regards
    Rebelsoul

  12. #12
    Registered User
    Join Date
    Mar 2009
    Posts
    9
    Hello,

    @ matsp you are right about the local declaration and yes i was doing that stupid mistake.
    Is SYNCMessage called from an interrupt or a different thread than main?
    You got me , SYNCMessage is an interrupt generated whenever my system in RX mode receives a SYNC.

    And are you ever intending to set RX_TEST to something other than 1 (e.g. reset it)
    Yes, i want to reset it in the if statement, so my system could always check and have a new value of this variable.

    Best Regards
    Rebelsoul

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, you then have to consider the fact that you are EXACTLY at the step before setting the flag to 0, and an interrupt comes in that sets it to 1. Then you set it to zero. If that happens, you have missed a message.

    You need some way to ENSURE that this doesn't happen.

    One way to do that is to ONLY write to it in the interrupt, and never change it's value in the main code. Typically, you would do that by counting in the interrupt function, and in main, you check if your CURRENT variable matches the count value. If not, do the processing and update the value in main (by counting up, if you copy the value from the interrupt updated variable, you could still get a race condition). I'd suggest you do this in a while-loop that keeps running around until the two numbers are equal.

    The other option is to have some sort of locking mechanism.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Mar 2009
    Posts
    9
    @matsp, do you want to say that i should do like that. I declared an extern variable in ABC.h

    Code:
    /* ABC.C*/
    #include "abc.h"
    USIGN8 RX_TEST=0; //declare globaly
    
    VOID SYNCMessage(VOID)
    
    {
         USIGN8 frameLen;
         USIGN8 rxBytes;
         //USIGN8 RX_TEST=0;
        
            
        if(SYNC_PIN_IS_HIGH())
        {
           IndSync();
        }
        else
        {
            
            if(RxActive)
            {
                //reset frame buffer
                USIGN8 i = 0;
                for(;i<0x3B;i++)
                {
                    INcomingPacket.frame[i-1] = 0x00;
                }
                
                  RX_TEST++; // incrementing
         }
    }
    Code:
    /*MAIN.C*/
    #include "abc.h"
    USIGN8 RX_TEST;
    
    void main (void)
    {
      USIGN8 RX_MODE=0;
    
         while(RX_MODE!=RX_TEST)
           {
               RX_MODE++;
           }  
    
        //here i will put my receive function
    
    }
    I hope, i have understand your guideline.

    Actually in my current program main i have used THREE extern variable which i placed in SYNCMessage. The first one is placed when i have an interrupt(SYNC) but there is no data received, second one when i have SYNC and Corrupted data and the third one when i have a complete receive packet. I am checking all these in three if and else-if statement. As my system is always in RX mode.

    Best Regards
    RebelSoul

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
               USIGN8 i = 0;
                for(;i<0x3B;i++)
                {
                    INcomingPacket.frame[i-1] = 0x00;
                }
    i = 0, i-1 = -1 -> out of bounds packet.

    Code:
         while(RX_MODE!=RX_TEST)
           {
               ... process packet of data ... 
               RX_MODE++;
           }
    was what I meant that you should do.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. using extern to have a global variable
    By steve1_rm in forum C Programming
    Replies: 3
    Last Post: 01-29-2009, 06:44 AM
  2. recursion error
    By cchallenged in forum C Programming
    Replies: 2
    Last Post: 12-18-2006, 09:15 AM
  3. 6 measly errors
    By beene in forum Game Programming
    Replies: 11
    Last Post: 11-14-2006, 11:06 AM
  4. OpenGL and Windows
    By sean345 in forum Game Programming
    Replies: 5
    Last Post: 06-24-2002, 10:14 PM
  5. My graphics library
    By stupid_mutt in forum C Programming
    Replies: 3
    Last Post: 11-26-2001, 06:05 PM

Tags for this Thread