snprintf issue when pass a macro - macros

define a macro somewhere
#define IDENTIFIER "identifier"
passing this macro into snprint()
char buf[SIZE] = {0};
if (snprintf(buf, sizeof(buf), "%08X_%08X_%s.zip", i, j, IDENTIFIER) >= SIZE)
{
return "";
}
however the result is:
10800000_00000A00_(null).zip
I don't know why its value is '(null)'. as we know, the macro is stored in symbol table of compiler, maybe it needs a pointer or reference here.
could anyone explain this?

Related

Directly assign UnsafePointer

Can somebody please explain to me what I'm missing here?
Given
let index: Int32 = 100
Why is this not okay:
// Use of extraneous '&'
let ptr = &index // Type inference?
Or even:
// Use of extraneous '&'
let ptr: UnsafePointer<Int32> = &index
But this is:
{
func point(num: UnsafePointer<Int32>) -> UnsafePointer<Int32> {
return num
}
let ptr = point(num: &index)
}
This would be the simple equivalent of this in C:
int index = 100;
int *ptr = &index;
Do I really have to define a function that literally takes the referenced value and passes back the very same reference? Something feels wrong about it. It seems like I'm missing something here, maybe even fundamental.
How do I assign an UnsafePointer to the memory address of the type it is (Int32 in this case)???
Thanks!
Edit:
Ultimately what I'm attempting to accomplish is, I need to write several various structures into a binary file. The variable index would be a property of a structure. The path I'm going down now involves a file OutputStream. I don't mind receiving suggestions on this, but gets out of scope of the original question.
I don't know the precise rationale, but presumably let ptr = &index isn't allowed because there's no guarantee that you can dereference ptr without invoking undefined behaviour (assuming index isn't a global or static stored variable – the only cases where Swift guarantees stable and unique pointer values).
Unlike other languages, Swift doesn't guarantee that a local variable will remain initialised until the end of the scope it's declared in – the optimiser is free to deinitialise it earlier. Allowing let ptr = &index would therefore make it far too easy to write unsound code.
It's worth noting that your example of:
func point(num: UnsafePointer<Int32>) -> UnsafePointer<Int32> {
return num
}
let ptr = point(num: &index)
is also unsound. Attempting to dereference ptr from let ptr = point(num: &index) is undefined behaviour, as the inout-to-pointer argument conversion produces a temporary pointer only valid for the duration of the function call.
If you want a scoped temporary pointer to a value, you can use withUnsafePointer(to:) – for example:
func baz() {
var foo = 5
withUnsafePointer(to: &foo) { ptr in
// use `ptr` here – do not escape it!
}
// In Swift 4.2 you can also use `withUnsafePointer(to:)` on let constants.
let bar = 5
withUnsafePointer(to: bar) { ptr in
// use `ptr` here – do not escape it!
}
}
Note that the pointer is only valid for the duration of the closure – attempting to escape it will lead to undefined behaviour.

Freeglut doesn't initialize when using it from Swift

I've tried to use the Freeglut library in a Swift 4 Project. When the
void glutInit(int *argcp, char **argv);
function is shifted to Swift, its declaration is
func glutInit(_ pargc: UnsafeMutablePointer<Int32>!, _ argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>!)
Since I don't need the real arguments from the command line I want to make up the two arguments. I tried to define **argv in the Bridging-Header.h file
#include <OpenGL/gl.h>
#include <GL/glut.h>
char ** argv[1] = {"t"};
and use them in main.swift
func main() {
var argcp: Int32 = 1
glutInit(&argcp, argv!) // EXC_BAD_ACCESS
glutInitDisplayMode(UInt32(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH));
glutCreateWindow("my project")
glutDisplayFunc(display)
initOpenGL()
glutMainLoop()
but with that I get Thread 1: EXC_BAD_ACCESS (code=1, address=0x74) at the line with glutInit().
How can I initialize glut properly? How can I get an UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>! so that it works?
The reason the right code in C char * argv[1] = {"t"}; does not work is because Swift imports fixed size C-array as a tuple, not a pointer to the first element.
But your char ** argv[1] = {"t"}; is completely wrong. Each Element of argv needs to be char **, but you assign char * ("t"). Xcode must have shown you a warning at first build:
warning: incompatible pointer types initializing 'char **' with an expression of type 'char [2]'
You should better take incompatible pointer types warning as error, unless you know what you are doing completely.
Generally, you should better not write some codes generating actual code/data like char * argv[1] = {"t"}; in a header file.
You can try it with Swift code.
As you know, when you want to pass a pointer to single element T, you declare a var of type T and pass &varName to the function you call.
As argcp in your code.
As well, when you want to pass a pointer to multiple element T, you declare a var of type [T] (Array<T>) and pass &arrName to the function you call.
(Ignoring immutable case to simplify.)
The parameter argv matches this case, where T == UnsafeMutablePointer<Int8>?.
So declare a var of type [UnsafeMutablePointer<Int8>?].
func main() {
var argc: Int32 = 1
var argv: [UnsafeMutablePointer<Int8>?] = [
strdup("t")
]
defer { argv.forEach{free($0)} }
glutInit(&argc, &argv)
//...
}
But I wonder if you really want to pass something to glutInit().
You can try something like this:
func main() {
var argc: Int32 = 0 //<- 0
glutInit(&argc, nil)
//...
}
I'm not sure if freeglut accept this, but you can find some articles on the web saying that this works in some implementation of Glut.

String transfer

I'd like to return a String back to Swift using this code:
MyFile.h:
+ (char *) myCoolCode;
MyFile.mm:
+(string)myCoolCode {
string myCoolString = "";
myCoolString += "123";
return myCoolString;
}
MyFile.swift:
let superCoolString = MyBridge.myCoolCode()
print(superCoolString)
But obviously it doesn't seems working the right way because it's crashing somewhere deep inside.
As others have already pointed out in the comments you should fix the return type of your .mm file to char * and not string. You should always keep those two types the same. An example of your function implementation can be:
- (char *)myCoolCode
{
char str[] = "foobar";
//You can do whatever you want with str here. Just make sure it's null terminated
return str;
}
Then in your swift code:
let myCoolString = String(cString: MyBridge.myCoolCode())
print(myCoolString)
Reference on the string constructor is here.
The reason your code was crashing is probably because you were returning an instance of std::string which doesn't really work in Swift. You can use std::string but you have to convert it to char * when returning it. You can do so as is shown here.

Why we used double and triple pointer in objective-C or C language?

I confused when i want to take single pointer and when should i take double pointer?
In following structure what exactly did?
struct objc_class {
Class isa;
Class super_class;
const char *name;
long version;
long info;
long instance_size;
struct objc_ivar_list *ivars;
struct objc_method_list **methodLists;
struct objc_cache *cache;
struct objc_protocol_list *protocols;
};
Why we use the methodLists double pointer?
Edited
int sqlite3_get_table(
sqlite3 *db,
const char *zSql,
char ***pazResult,
int *pnRow,
int *pnColumn,
char **pzErrmsg
);
In above scenario what will be meaning of triple pointer char ***pazResult?
Well, in C at least, double-pointers are commonly used for 2D arrays. The most common 2D array is probably an array of C strings (char*'s). Double pointers are also sometimes employed to pass pointers to functions by reference, but this is unlikely to be the use in the code sample you posted.
According to the name methodLists I would guess that this is an array of lists. A (linked) list in C is commonly represented by a pointer to a node, which objc_method_list could be. An array of such lists is then implemented with a double pointer.
It's probably not the case in the code that you referenced, but you also need a double pointer any time you want to pass a pointer to a function and have changes to that pointer be reflected outside the scope of that function.
For example, if you were trying to rewrite the strcpy function so that the user did not have to allocate memory for the source string, you might try something like the following:
void MyStrcpy(char* dst, char* src){
dst = (char*)malloc(sizeof(char)*(strlen(src)+1));
for(int i=0;i<=strlen(src);i++)
dst[i] = src[i];
printf("src: %s ", src);
printf("dst: %s\n\n", dst);
}
If you were then to call that function,
int main() {
char *foo = "foo";
char *newPtr;
MyStrcpy(newPtr, foo);
printf("foo: %s ", foo);
printf("new: %s\n", newPtr);
}
your output would be as follows:
src: foo
dst: foo
foo: foo
new:
You might also get a seg fault when trying to print newPtr, depending your system. The reason for this behavior is the exact same as the reason you wouldn't expect a change to an int that was passed by value to a function to be reflected outside of that function: what you are passing to MyStrcpy is simply the memory address that newPtr references. When you malloc the space for dst inside the function, you are changing the address dst points to. This change will not be reflected outside of the scope of MyStrcpy!
Instead, if you wanted newPtr to point to the new allocated chunk of memory, you need to have dst be a pointer to a pointer, a char **.
void MyStrcpy(char** dst, char* src){
*dst = (char*)malloc(sizeof(char)*(strlen(src)+1));
for(int i=0;i<=strlen(src);i++)
(*dst)[i] = src[i];
printf("src: %s ", src);
printf("dst: %s\n\n", *dst);
}
Now, if you were to call that function:
int main() {
char *foo = "foo";
char *newPtr;
MyStrcpy(&newPtr, foo);
printf("foo: %s ", foo);
printf("new: %s\n", newPtr);
}
You would get your expected output:
src: foo
dst: foo
foo: foo
new: foo
Hope that helps!
See also these questions:
What is double star?
Why does NSError need double indirection? (pointer to a pointer)
In the most general case a double pointer is a pointer to a list of pointers.
In general pointer is used to hold the address of another variable. What if we need to hold the address of pointer ,in that case we use double pointer. When we want to hold the address of double pointer we use triple pointer.

What does error conflicting types for '' mean?

i got an error that said "error: conflicting types for '____'. What does that mean?
Quickfix:
Make sure that your functions are declared once and only once before they are called. For example, change:
main(){ myfun(3.4); }
double myfun(double x){ return x; }
To:
double myfun(double x){ return x; }
main(){ myfun(3.4); }
Or add a separate function declaration:
double myfun(double x);
main(){ myfun(3.4); }
double myfun(double x){ return x; }
Possible causes for the error
Function was called before being declared
Function defined overrides a function declared in an included header.
Function was defined twice in the same file
Declaration and definition don't match
Declaration conflict in the included headers
What's really going on
error: conflicting types for ‘foo’ means that a function was defined more than once with different type signatures.
A file that includes two functions with the same name but different return types would throw this error, for example:
int foo(){return 1;}
double foo(){return 1.0;}
Indeed, when compiled with GCC we get the following errors:
foo.c:5:8: error: conflicting types for ‘foo’
double foo(){return 1.0;}
^
foo.c:4:5: note: previous definition of ‘foo’ was here
int foo(){return 1;}
^
Now, if instead we had a file with two function definitions with the same name
double foo(){return 1;}
double foo(){return 1.0;}
We would get a 'redefinition' error instead:
foo.c:5:8: error: redefinition of ‘foo’
double foo(){return 1.0;}
^
foo.c:4:8: note: previous definition of ‘foo’ was here
double foo(){return 1;}
^
Implicit function declaration
So why does the following code throw error: conflicting types for ‘foo’?
main(){ foo(); }
double foo(){ return 1.0; }
The reason is implicit function declaration.
When the compiler first encounters foo() in the main function, it will assume a type signature for the function foo of int foo(). By default, implicit functions are assumed to return integers, and the input argument types are derived from what you're passing into the function (in this case, nothing).
Obviously, the compiler is wrong to make this assumption, but the specs for the C (and thus Objective-C) language are old, cranky, and not very clever. Maybe implicitly declaring functions saved some development time by reducing compiler complexity back in the day, but now we're stuck with a terrible feature that should have never made it into the language. In fact, implicit declarations were made illegal in C99.
That said, once you know what's going on, it should be easy to dig out the root cause of your problem.
it's probably because your function "_" already exists in your library. It happened to me with this function:
I was using stdio.h
int getline (char s[ ] , int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
When I changed "getline" to "getlinexxx" and gcc compiled it:
int getlinexxx (char s[], int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
And the problem was gone
What datatype is '___'?
My guess is that you're trying to initialize a variable of a type that can't accept the initial value. Like saying int i = "hello";
If you're trying to assign it from a call that returns an NSMutableDictionary, that's probably your trouble. Posting the line of code would definitely help diagnose warnings and errors in it.