简体   繁体   中英

static bool defined in header works for one file only, why?

I'm new in Objective-C

I try to integrate asl_log . For some reason static bool always has NO value in other files.

I created header MyLogger.h with content:

#import <Foundation/Foundation.h>
#import <asl.h>

static bool gLoggingEnabled = NO;

#define __AF_MAKE_LOG_FUNCTION(LEVEL, NAME) \
static inline void NAME(NSString *format, ...)\
{ \
  if (!gLoggingEnabled) return; \
  va_list arg_list; \
  va_start(arg_list, format); \
  NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list]; \
  asl_add_log_file(NULL, STDERR_FILENO); \
  asl_log(NULL, NULL, (LEVEL), "Prog_ASL:  %s", [formattedString UTF8String]); \
  va_end(arg_list); \
}    

__AF_MAKE_LOG_FUNCTION(ASL_LEVEL_DEBUG, AFLogDebug)



#undef __AF_MAKE_LOG_FUNCTION

You can see that I use static bool gLoggingEnabled as switch.

From my main project file I do:

#import "AFLogger.h"

// ...

gLoggingEnabled = YES;

if (gLoggingEnabled) {
    asl_add_log_file(NULL, STDERR_FILENO);
    //set log level
    asl_set_filter(NULL, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
} else {
    asl_remove_log_file(NULL, STDERR_FILENO);
}  

AFLogDebug(@"flag is %@", gLoggingEnabled ? @"Yes" : @"No");
 // -> flag is Yes

However it works only in one file.

I have other .m file:

 #import "AFLogger.h"

 //...
 NSLog(@"flag is %@", gLoggingEnabled ? @"Yes" : @"No");
 // -> flag is No

 // AFLogDebug prints nothing

Why static bool gLoggingEnabled has No value in other files

How to fix it?

[EDIT]

I want to avoid to use extern

It's static so each .m file that you import MyLogger.h into gets its own copy of the gLoggingEnabled variable.

If you want a single, app-wide variable, then you need to change 2 things.

In MyLogger.h you need to change static to extern :

extern bool gLoggingEnabled;

In MyLogger.m you need to add:

bool gLoggingEnabled = NO;

That declaration pairs with the extern . This is the app-wide global variable.

Then in any file, you can change its value:

gLoggingEnabled = YES; // or NO as needed

That last line will change the value for the entire app (any file that includes MyLogger.h ).

What you have there is a definition of the variable. What you want is a declaration. Not only that, the static modifier limits its visibility to the compilation unit it is defined in. Essentially, every .c or .m file has its own copy of gLoggingEnabled which only it can see.

What you need to do is create a non static file scope variable in in one .c or .m file

bool gLoggingEnabled = false; // Note, using C11 bool definitions

Then you add an external declaration in the header. This is like a promise to the compiler that you may not have defined the storage for the variable in the current compilation unit, but it will be done at link time.

extern bool gLoggingEnabled;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM