I have a "MyConstants.h" file that is imported by several classes.
Inside that file I have things like:
static BOOL isIndexValid(NSInteger index) {
return ((index >=0) && (index < 200));
}
This function is extensively used by the classes importing MyConstants.h. Even so, Xcode complains that this function and others are not used.
Why?
Defining a static function (or variable, for that matter) in a header file means every source file that imports that header file will get its own copy.
That is not good and is what the compiler is complaining about (not every source file references this function).
Make it static inline instead:
static inline BOOL isIndexValid(NSInteger index) {
return ((index >=0) && (index < 200));
}
Try to insert __unused between return type and function name, and it works for me on Xcode 10.2
static BOOL __unused isIndexValid(NSInteger index) {
return ((index >=0) && (index < 200));
}
Hope it will be helpful for you.
Related
I'm trying to register a custom CodeInsight manager into C++Builder 10.1.2 Berlin.
Because there's nothing like Objects Pascal's initialization and finalization sections in C++, e.g.
var
codeManagerIndex: Integer;
{...}
initialization
codeManagerIndex := (BorlandIDEServices as IOTACodeInsightServices).AddCodeInsightManager(TMyCodeInsightManager.Create);
finalization
(borlandIDEServices as IOTACodeInsightServices).RemoveCodeInsightManager(codeManagerIndex);
end.
I tried reproducing their behavior with a custom runner class with constructor/destructor:
class Runner
{
public:
int FCodeManagerIndex;
_di_IOTACodeInsightServices CIS;
Runner() {
if (BorlandIDEServices->Supports(CIS))
FCodeManagerIndex = CIS->AddCodeInsightManager(new TMyCodeInsightManager);
}
~Runner() {
if (BorlandIDEServices->Supports(CIS))
CIS->RemoveCodeInsightManager(FCodeManagerIndex);
}
};
#pragma argsused
extern "C" int _libmain(unsigned long reason)
{
Runner Run;
return 1;
}
I can compile my simple implementation but when I try to install the package the following things are happening:
1st try: Error message: Can't load package ... mypackage.bpl - A dynamic link library (DLL) initialization routine failed.
2nd try: An exception (C0000005) occured during DllEntryPoint or DllMain in module: ... mypackage.bpl ... then the IDE crashes.
Is this a wrong way to register?
What am I doing wrong here?
P.S. I get a [TLIB Warning] Warning: library was too large for page size, rebuilt with page size 32 warning when compiling, but I'm quite sure that this can't be the reason for my errors. (?)
there's nothing like Objects Pascal's initialization and finalization sections in C++
Actually, there is. In C++Builder, you can use #pragma startup and #pragma exit to execute user-defined functions:
static int FCodeManagerIndex = -1;
void DoRegister() {
_di_IOTACodeInsightServices CIS;
if (BorlandIDEServices->Supports(CIS)) {
FCodeManagerIndex = CIS->AddCodeInsightManager(new TMyCodeInsightManager);
}
}
#pragma startup DoRegister
void DoUnregister() {
_di_IOTACodeInsightServices CIS;
if ((FCodeManagerIndex != -1) && BorlandIDEServices->Supports(CIS)) {
CIS->RemoveCodeInsightManager(FCodeManagerIndex);
}
}
#pragma exit DoUnregister
#pragma argsused
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
Alternatively, since you ready declared a class to handle your registration, you can simply move your class variable into global static memory so its constructor runs at startup and destructor runs at shutdown:
class Runner
{
public:
int FCodeManagerIndex;
Runner() : FCodeManagerIndex(-1) {
_di_IOTACodeInsightServices CIS;
if (BorlandIDEServices->Supports(CIS)) {
FCodeManagerIndex = CIS->AddCodeInsightManager(new TMyCodeInsightManager);
}
}
~Runner() {
_di_IOTACodeInsightServices CIS;
if ((FCodeManagerIndex != -1) && BorlandIDEServices->Supports(CIS)) {
CIS->RemoveCodeInsightManager(FCodeManagerIndex);
}
}
};
static Runner Run;
#pragma argsused
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
Declaring the class variable inside of _libmain() is useless since the destructor will be called when the variable goes out of scope when _libmain() exits, thus unregistering the manager immediately after registering it. So the variable has to survive for as long as the package is loaded in memory.
The page http://www.sqlite.org/threadsafe.html mentions:
Single-thread
Multi-thread
Serialized
How can we implement that threads in Swift. Or how to use sqlite3_config(SQLITE_CONFIG_MULTITHREAD in Swift
Instead of sqlite3_config you can add the required options when opening the database. This is only available for sqlite3_open_v2, not for sqlite3_open or sqlite3_open16.
Here is an example:
let rc = sqlite3_open_v2(databasePath, &db, SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX, nil)
For anyone who ended up here looking for a way to call sqlite3_config (regardless of the threading question) using the built-in SQLite3 module...
The reason it's not available is that it uses ellipsis-style variadic arguments, which according to this are not supported in Swift. One way to get around this is to make your own C header with wrapper functions for calling sqlite3_config with whatever (non-variadic) argument arrangement you need.
For example, a "bridging header" with something like this covers all the valid call signatures you might need (as far as what the SQLite config options require):
#ifndef SqliteConfig_h
#define SqliteConfig_h
#import "sqlite3.h"
static inline int sqlite3_config_no_args(int op) {
return sqlite3_config(op);
}
static inline int sqlite3_config_ptr(int op, void* arg1) {
return sqlite3_config(op, arg1);
}
static inline int sqlite3_config_int(int op, int arg1) {
return sqlite3_config(op, arg1);
}
static inline int sqlite3_config_ptr_int_int(int op, void* arg1, int arg2, int arg3) {
return sqlite3_config(op, arg1, arg2, arg3);
}
static inline int sqlite3_config_int_int(int op, int arg1, int arg2) {
return sqlite3_config(op, arg1, arg2);
}
static inline int sqlite3_config_ptr_ptr(int op, void* arg1, void* arg2) {
return sqlite3_config(op, arg1, arg2);
}
#endif /* SqliteConfig_h */
Maybe there are cleaner or more idiomatic ways to create these kinds of wrappers (rather than static-inline functions in a bridging header). I'm not an expert in this area. But considering they're just wrapping calls, it seems like a good lightweight workaround.
You can search around for more info on bridging headers if you don't know how to create one. But in short: You can create a bridging header "manually" (after creating your .h file) by going to Build Settings/Swift Compiler - General/Objective-C Bridging Header and setting the value to the header filename you created. If you don't do that, your .h file is ignored. Or you could create one automatically (without going into the compiler settings) by dragging a dummy .c file into the project, deleting that file, and then editing the header it created. Or do that with a "real" C file if you prefer your code there rather than inline.
With that in place, here's an example of using sqlite3_config to install your own logging callback:
import SQLite3
func errorLogCallback(_: OpaquePointer?, iErrCode: Int, zMsg: UnsafePointer<CChar>)
{
let s = String(cString: zMsg)
print("LOG:", iErrCode, s)
}
let cCallbackPtr: #convention(c) (OpaquePointer?, Int, UnsafePointer<CChar>) -> () = errorLogCallback
let rawPtr = unsafeBitCast(cCallbackPtr, to: UnsafeMutableRawPointer.self)
sqlite3_config_ptr_ptr(SQLITE_CONFIG_LOG, rawPtr, nil)
Consider the following code which prints out the even numbers up to 20:
import std.stdio;
class count_to_ten{
static int opApply()(int delegate(ref int) dg) {
int i = 1;
int ret;
while(i <= 10){
ret = dg(i);
if(ret != 0) {
break;
}
i++;
}
return ret;
}
}
void main() {
int y = 2;
foreach(int x; count_to_ten) {
writeln(x * y);
}
}
The syntax of opApply requires that it take a delegate or function as a normal argument. However, even if we relaxed that and allowed opApply to take a function as a template argument, we still would have no recourse for delegates because D doesn't provide any way to separate the stack-frame pointer from the function pointer. However, this seems like it should be possible since the function-pointer part of the delegate is commonly a compile-time constant. And if we could do that and the body of the loop was short, then it could actually be inlined which might speed this code up quite a bit.
Is there any way to do this? Does the D compiler have some trick by which it happens automagically?
The previous version of dart was able to get getters using
cm.getters.values
As is posted in this answer: https://stackoverflow.com/a/14505025/2117440
However actual version was removed that featured and replaced by
cm.declarations.values
The last code gets all attributes, getters, setters, methods, and constructors. I would like to know if there is a way to get only "getters and attributes" without other methods.
The code that I'm using right now is that one:
import "dart:mirrors";
class MyNestedClass {
String name;
}
class MyClass {
int i, j;
MyNestedClass myNestedClass;
int sum() => i + j;
MyClass(this.i, this.j);
}
void main() {
MyClass myClass = new MyClass(3, 5)
..myNestedClass = (new MyNestedClass()..name = "luis");
print(myClass.toString());
InstanceMirror im = reflect(myClass);
ClassMirror cm = im.type;
Map<Symbol, MethodMirror> instanceMembers = cm.instanceMembers;
cm.declarations.forEach((name, declaration) {
if(declaration.simpleName != cm.simpleName) // If is not te constructor
print('${MirrorSystem.getName(name)}:${im.getField(name).reflectee}');
});
}
As you can see in the previous code to check if is not the constructor I need to compare the declaration.simpleName with cm.simpleName. Until I understand is inefficient since we are comparing strings.
In conclusion, I would like to know if there is or will be a better way to solve this problem.
Maybe there is a better way but this should provide what you need
cm.declarations.forEach((name, declaration) {
VariableMirror field;
if(declaration is VariableMirror) field = declaration;
MethodMirror method;
if(declaration is MethodMirror) method = declaration;
if(field != null) {
print('field: ${field.simpleName}');
} else if(method != null && !method.isConstructor){
print('method: ${method.simpleName}');
}
});
After casting to VariableMirror or MethodMirror you can get a lot more properties:
field:
- isConst
- isFinal
- isStatic
method:
- constructorName
- isConstructor
- isConstConstructor
- isFactoryConstructor
- isGenerativeConstructor
- isGetter
- isOperator
- isRedirectingConstructor
- isRegularMethod
- isSetter
- isStatic
- isSynthetic
I've got this beautiful & convenient helper inline function that i have in a project (originally has it's roots in here & here):
static inline BOOL isEmpty(id thing) {
return !thing
|| [thing isKindOfClass:[NSNull class]]
|| ([thing respondsToSelector:#selector(length)] && [((id)thing) length] == 0)
|| ([thing respondsToSelector:#selector(count)] && [((id)thing) count] == 0);
}
static inline BOOL isNotEmpty(id thing) {
return !isEmpty(thing);
}
and all works well.
it's useful for checking NSString, NSData, NSArray, NSDictionary, NSSet, and others... My issue now is that I brought it in to another project(a static framework/library that i'll be using) and have the following issue that is stopping my project from building:
I'm using the same(latest) version of xCode with both so not sure what the difference could be that would stop this on one side and not the other... The project settings are obviously different in either project (as mentioned, one is a framework and one is a regular project) but would that do it?
thanks in advance!
POST-SOLUTION-EDIT for future visits:
hold command and click on the method or property to get a drop down of all the instances that the compiler is seeing... you likely have conflicting return types.
It sounds like the problem is that some class(es) in the framework/library declares a -count method that returns something different than -[NSArray count] (etc.).
Even when you're sending a message to an object of unknown (id) type, the compiler needs to know some information about the method that will be called, including the return type. In short, this is because the message send path is different depending on the return type of the method that will be called. In cases like your code, the compiler will look for any method declared in the project with a name matching the message you're sending, and assume that's the method that will be called for the purposes of figuring out return type, etc. In this case, it's finding two different methods with the same name, but which have differing return types, and therefore doesn't know the exact semantics required for sending the count message.
The quick and dirty solution is to change the cast in your isEmpty() function to [(NSArray *)thing count]. This should work fine as long as you never call isEmpty() with instances of whatever class it is that has a different -count method.
update: changed the sense of the method to is not empty, to handle nil values too.
Not quite an answer, but you could do this with categories:
#interface NSObject (IsEmpty)
-(BOOL)isNotEmpty ;
#end
#implementation NSObject (IsEmpty)
-(BOOL)isNotEmpty { return NO ; /* I guess? */ }
#end
#implementation NSArray (IsEmpty)
-(BOOL)isNotEmpty { return self.count > 0 ; }
#end
#implementation NSDictionary (IsEmpty)
-(BOOL)isNotEmpty { return self.count > 0 ; }
#end
#implementation NSSet (IsEmpty)
-(BOOL)isNotEmpty { return self.count > 0 ; }
#end
#implementation NSNull (IsEmpty)
-(BOOL)isNotEmpty { return NO ; }
#end
Now you can do this:
id objectOrNil = ... ;
BOOL isEmpty = ![ objectOrNil isNotEmpty ] ;
I guess the proper way would be to explicitly cast the result of [thing count] to integer:
static inline BOOL isEmpty(id thing) {
return !thing
|| [thing isKindOfClass:[NSNull class]]
|| ([thing respondsToSelector:#selector(length)] && [((id)thing) length] == 0)
|| ([thing respondsToSelector:#selector(count)] && (NSUInteger)[((id)thing) count] == 0);
}
This will tell compiler that you expect to see unsigned integer as a result of this method invocation.
static inline BOOL isEmpty(id thing) {
return !thing
|| [thing isKindOfClass:[NSNull class]]
|| ([thing respondsToSelector:#selector(length)]
&& [(NSData *) thing length] == 0)
|| ([thing respondsToSelector:#selector(count)]
&& [(NSArray *) thing count] == 0);
}
It shouldn't confuse with [NSArray count] method. Hope that will help.