declaring and passing char array of different sizes correctly - iphone

I like to define a method that receives a char array of variable size.
This is my current definition:
+(int) findStartIndex: (NSData*)buffer searchPattern: (char*) searchPattern;
And this is where I call it:
const char a[] = {'a','b','c'};
startIndex = [self findStartIndex:buffer searchPattern: a];
and like this
const char b[] = {'1','2'};
startIndex = [self findStartIndex:buffer searchPattern: b];
But I keep getting the compiler warning:
Sending 'const char[3]' to parameter of type 'char *' discards qualifiers
and
Sending 'const char[2]' to parameter of type 'char *' discards qualifiers
respectively.
How to do this correctly?

Because the parameter you declared as char *, but const char [] is passed. It's a have a potential risk. you should the following changes. Do not have a warning when I tested.
+(int) findStartIndex: (NSData*)buffer searchPattern: (const char*) searchPattern

Qualifiers in C apply to the keyword on the left first, then fallback to the right next. const char arr[] is not a constant reference to a char array, it's always of type char. But, when you pass it to a method that takes a pointer to char, then you lose the const'ness of the type, and you get a warning. (Hooray for obscure C stuff!)

Related

Eclipse CDT isConst check

I have a simple Pointer.c file:
#include<stdio.h>
// Pointer To Constant
const int* ptrToConst ;
//Constant Pointer
int* const ConstPtr ;
When I parse it through Eclipse CDT:
File f = new File("C:/Data/Pointer.c");
IASTTranslationUnit ast = ASTProvider.getInstance().getASTWithoutCache(f);
for (IASTDeclaration d : ast.getDeclarations()) {
IASTSimpleDeclaration sd = (IASTSimpleDeclaration) d;
System.out.println("Variable Name: " + sd.getDeclarators()[0].getName());
System.out.println("Is Constant: " + sd.getDeclSpecifier().isConst() + "\n");
}
The output is:
Variable Name: ptrToConst
Is Constant: true
Variable Name: ConstPtr
Is Constant: false
As per the output, the first variable which is pointer to constant is parsed as constant while the other one, a constant pointer is not. I don't understand this behavior, why is it so? Does CDT understand the pointer variables differently? As per my understanding the output should be the exactly reverse of it.
Check the variable d detail for 2nd case at the time of debugging:
Since (see this answer)
const int* ptrToConst declares a pointer (that can be modified) to a constant integer and
int* const ConstPtr declares a contant pointer to an integer (that can be modified),
in the second case sd.getDeclSpecifier().isConst() returns false.
So in the second case, the const modifier can be found deeper in the abstract syntax tree at the pointer operators instead (as you have found out yourself).

char *ptr ---> New to C

Declared char array (read-only):
const char alpha [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Given a char pointer called ptr and the alpha array declared above, how would I make ptr point to the letter 'D'?
I think its ---> char *alpha[3]; because its pointing to the third index of the array.
Here you go
D is 3 index away from starting address of alpha that is A.
So your pointer should be initialized like this
char *ptr = alpha + 3;

Why do XS subs use const char *?

A lot of Perl XS code uses const char * as the return value of an XS sub but never just char *. For example:
const char *
version(...)
CODE:
RETVAL = chromaprint_get_version();
OUTPUT: RETVAL
code from xs-fun
Can someone explain why const is preferred? In my testing, the returned scalar is modifiable whether const is used or not.
It's only for clarity. The chromaprint_get_version function returns a const char *, so the XSUB should be defined with a const char * return type as well. If you have a look at the built-in typemap, it doesn't make a difference whether you use const char *, char *, or even unsigned char *. They all use the T_PV typemap. In all cases, the XSUB will return an SV containing a copy of the C string, which is always modifiable.

store string in char array assignment makes integer from pointer without a cast

#include <stdio.h>
int main(void){
char c[8];
*c = "hello";
printf("%s\n",*c);
return 0;
}
I am learning pointers recently. above code gives me an error - assignment makes integer from pointer without a cast [enabled by default].
I read few post on SO about this error but was not able to fix my code.
i declared c as any array of 8 char, c has address of first element. so if i do *c = "hello", it will store one char in one byte and use as many consequent bytes as needed for other characters in "hello".
Please someone help me identify the issue and help me fix it.
mark
i declared c as any array of 8 char, c has address of first element. - Yes
so if i do *c = "hello", it will store one char in one byte and use as many consequent bytes as needed for other characters in "hello". - No. Value of "hello" (pointer pointing to some static string "hello") will be assigned to *c(1byte). Value of "hello" is a pointer to string, not a string itself.
You need to use strcpy to copy an array of characters to another array of characters.
const char* hellostring = "hello";
char c[8];
*c = hellostring; //Cannot assign pointer to char
c[0] = hellostring; // Same as above
strcpy(c, hellostring); // OK
#include <stdio.h>
int main(void){
char c[8];//creating an array of char
/*
*c stores the address of index 0 i.e. c[0].
Now, the next statement (*c = "hello";)
is trying to assign a string to a char.
actually if you'll read *c as "value at c"(with index 0),
it will be more clearer to you.
to store "hello" to c, simply declare the char c[8] to char *c[8];
i.e. you have to make array of pointers
*/
*c = "hello";
printf("%s\n",*c);
return 0;
}
hope it'll help..:)

IPhone SDK - How to detect variable type (float or double)?

How do I detect whether a variable is float, double, int, etc.?
Thanks.
Objective-C is not like PHP or other interpreted languages where the 'type' of a variable can change according to how you use it. All variables are set to a fixed type when they are declared and this cannot be changed. Since the type is defined at compile time, there is no need to query the type of a variable at run-time.
For example:
float var1; // var1 is a float and can't be any other type
int var2; // var2 is an int and can't be any other type
NSString* var3; // var3 is a pointer to a NSString object and can't be any other type
The type is specified before the variable name, also in functions:
- (void)initWithValue:(float)param1 andName:(NSString*)param2
{
// param1 is a float
// param2 is a pointer to a NSString object
}
So as you can see, the type is fixed when the variable is declared (also you will notice that all variables must be declared, i.e. you cannot just suddenly start using a new variable name unless you've declared it first).
In a compiled C based language (outside of debug mode with symbols), you can't actually "detect" any variable unless you know the type, or maybe guess a type and get lucky.
So normally, you know and declare the type before any variable reference.
Without type information, the best you can do might be to dereference a pointer to random unknown bits/bytes in memory, and hopefully not crash on an illegal memory reference.
Added comment:
If you know the type is a legal Objective C object, then you might be able to query the runtime for additional information about the class, etc. But not for ints, doubles, etc.
Use sizeof. For double it will be 8. It is 4 for float.
double x = 3.1415;
float y = 3.1415f;
printf("size of x is %d\n", sizeof(x));
printf("size of y is %d\n", sizeof(y));