Ultimately I'm trying to pull out relevant structures from thousands of existing c and c++ header files. I've been able to use libtooling to pull out a structure and all of the structures/enums/typedefs etc it relies on from various different headers. Unfortunately when I get the source backing the Decls it still references the macros defined there in. I'm currently trying to find a way to access and print the source of these macros but not having much luck when multiple macros are defined.
For example:
#define INT int
#define UNSIGNED unsigned
#define NAME name
typedef struct {
UNSIGNED long INT NAME;
} test;
When I get the FieldDecl corresponding to name and get the SourceRange I see the spelling location pointing to "#define UNSIGNED unsigned". I'd like to know how to get to the other macro definition's source locations. I know that when I change "UNSIGNED long INT NAME;" to "unsigned long INT NAME;" the spelling location will then point to "#define INT int". It seems as if names are treated differently as changing to "unsigned long int NAME;" leaves me with no spelling location.
Is there a way to get multiple spelling locations given a SourceRange? Do I need to narrow down the source range some other way? I've tried lexing to the next token but the doesn't leave me with a new spelling location. I'm also going to have to account for macros in arrays such as "int bob[MAX_WIDTH][MAX_HEIGHT]" but I'm hoping once I figure out my issues here that will become clear. Thanks in advance for any help that can be provided.
Related
Previously I had a method that does some task which takes in a BOOL.
-(void)processUserBasedonStatus:(BOOL)newUser
I then defined an NS_ENUM to accept more states like this
typedef NS_ENUM(NSInteger, Status)
{
StatusNewUser=0,
StatusCurrentUser,
StatusOldUser,
StatusOther
};
And updated the method to use the new ENUM param
-(void)processUserBasedonStatus:(Status)userStatus
Everything works well, except that Xcode didn't complain about some places where I forgot to update the calling method, i.e.
[self processUserBasedonStatus:YES];
[self processUserBasedonStatus:NO];
In this case, YES & NO will only map to the top 2 values of the ENUM. I experimented with the list of warnings in Xcode but nothing allows the compiler to bring up this warning.
Is there a way to enable the compiler to warn us about this type of behavior?
In (Objective-)C the types _Bool, char, int, long et al and their unsigned counterparts are all integer types. Types defined by enum are not distinct types per se but a collection of constants of their underlying integer type.
The Objective-C type BOOL is either a synonym (typedef or #define) for _Bool or one of the char types, depending on the version of the compiler.
Due to integer promotions and integer conversions many assignments between different integer types are automatic and silent. Even floating point types can get involved, e.g.:
bool b = true;
float f = b;
is perfectly legal and might well go uncommented by a compiler even as a warning.
Given all this the answer to your question:
Is there a way to enable the compiler to warn us about this type of behaviour?
is currently it seems “no” – the code is perfectly legal in (Objective-)C. It is however dubious and could indicate an error and there is nothing stopping the compiler issuing a warning as it does for some other legal but dubious constructs. You could submit a report to Apple at bugreport.apple.com (you need an Apple ID to do this) suggesting they add such a warning.
I've an app in which I need to send a packet to an external device. This packet has a CRC before the end message. The CRC has to be separated in CRCH and CRCL.
For example: CRC = 0x5B so CRCH should be 0x35 (ASCII representation of 5) and CRCL should be 0x42 (ASCII representation of B).
I searched on internet and I found several functions in C or in other language to create CRC32, but my device need to use a CRC8. How I can create a CRC8 in Objective-C? Can you help me to find a way to do this?
Surprising how this rather simple question is still not answered.
First, you need to separate problems in your question. CRH and CRL are just hex conversion and that's easy to do (and has lots of examples on internet too). In most cases, you just need to compare crc you received to one you calculated. So, you just need to convert them to the same form. E.g. convert the crc you calculated to text using sprintf and %2X format and compare with CRC you received (as text).
The second part is actually CRC. This is a little bit trickier.Your options are as follows:
1) the easiest is to rename your .m file to .mm and use CRC library from boost C++. It's just a header include, so it won't affect rest of your code in any way and you can even make it in a separate file, so you'll have a C function which will use boost under the hood.
You might need to find parameters for your CRC though. For that, see this excellent resource http://reveng.sourceforge.net/crc-catalogue/
2) You can write your own implementation. Surprisingly there is plenty of examples for particular algorithms in the internet, but they often optimized for particular crc and are hard to adopt for other algorithms.
So, your best bet is probably starting with "A Painless Guide to CRC Error Detection Algorithms" article by Ross Williams. It also includes examples in C.
Though it could be complicated to get your head around all the technical stuff and explanations there.
So, as as short cut I'd like to suggest to look at my own implementation in java here. It's obviously not Objective-C. But I looked through it and you should be able to just copy and paste to your .m file and just compile it. Possibly adjusting few types.
You'll need public static long calculateCRC(Parameters crcParams, byte[] data) and private static long reflect(long in, int count) functions there. And the Parameters class which looks scarier, but should just become a struct in your case:
struct Parameters
{
int width; // Width of the CRC expressed in bits
long polynomial; // Polynomial used in this CRC calculation
bool reflectIn; // Refin indicates whether input bytes should be reflected
bool reflectOut; // Refout indicates whether input bytes should be reflected
long init; // Init is initial value for CRC calculation
long finalXor; // Xor is a value for final xor to be applied before returning result
}
You might also want to also adjust types there to a shorter unsigned type (java has no unsigned). But it should work perfectly well as is.
C functions like memcpy and memset are available as C functions as well as #define in iOS:
For example the #define memcpy, under the hood, is:
#define memcpy(dest, src, len) \
((__darwin_obsz0 (dest) != (size_t) -1) \
? __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest)) \
: __inline_memcpy_chk (dest, src, len))
I gather there is some memory checking here but can someone shed some additional details on why it is better than a memcpy alone (where is the value added)?
More importantly, when to use which?
Those names, such as __inline_memcpy_chk, are used by the compiler to help it optimize uses of memcpy. They are special names that corresponding to built-in features of the compiler. They assist it in converting certain uses of memcpy into code that is faster than calling the memcpy library routine. The result might be simple move instructions or, even more efficiently, simple changes of information inside the compiler, so that it knows a copy of a value is available in a register.
If you undefine the macro memcpy so that these built-in features are not used, which is permitted by the C standard, the memcpy routine will still work, but it may be less efficient than if you left it alone.
Generally, you should not try to call these internal names yourself. They have been designed and defined to make the normal use of memcpy efficient.
Unless you #undef the macro, or call it like this (memcpy)(args...), it will always use the macro variant.
I would personally just use the maco - it's intended to be fast and efficient, and will work as you expect.
To answer your questions,
1) I have no additional details, but peeking under the hood like that violates the abstraction the authors have provided for you. You want memcpy, you've got memcpy as they've provided it there, implemented with the snippet you're showing. If you're curious how it works, you can dig into it, but because you asked "when to use which" I suspect you're trying to figure out something that works in practice. Which gets to the answer to your second question...
2) You should use memcpy(dest, src, len). Don't hack around the #define and use the underlying code in a way that was not intended. You're provided with memcpy() as it is there; for you, that is memcpy.
Does it make a difference which one I use in objective-c (particularly on iOS)? I assume it comes from inheriting from C and its types, as well as inheriting the types from Mac OS, which iOS was based on, but I don't know which one I should use:
unsigned char from...well..the compiler?
uint8_t from stdint.h
UInt8 from MacTypes.h
Byte from MacTypes.h
Bytef from zconf.h
I am aware that the various defs are for portability reasons, and using literals like unsigned char is not good future thinking (size might change, and things will end up like the Windows API again). I'd like some advice on how to spot the best ones for my uses. Or a good tongue lashing if I'm just being silly...
EDIT : Just for some more info, if I want something that will always be 1 byte, should I use uint8_t (doesn't seem like it would change with a name like that)? I'd like to think UInt8 wouldn't change either but I see that the definition of UInt32 varies on whether or not the processor is 64-bit.
FURTHER EDIT : When I say byte, I specifically mean that I want 8 bits. I am doing pixel compression operations (32 bits -> 8 bits) for disk storage.
It's totally indifferent. Whichever you use, it will most probably end up being an unsigned char. If you want it to look nice, though, I suggest you use uint8_t from <stdint.h>.
Neither will change with the architecture. char is always 1 byte as per the C standard, and it would be insupportable from a user's point of view if in an implementation, UInt8 suddenly became 16 bits long.
(It is not the case, however, that char is required to be 8 bits wide, it's only that if the name of a type suggest that it's 8 bits long, then any sensible implementation does indeed typedefs it as such. Incidentally, a byte (which char is) is often an 8-bit unit, i. e. an octet.)
As in every programming language derived from C-language type model, Objective C has a handful of equivalent options to declare a 8-bit integer.
Why did I say equivalent? Because as OP correctly stated, it's obvious that all of those options eventually typedef-ed to unsigned char built-in compiler type. This is correct for now and, let's speak practically, nobody sane will change them to be a non-8-bit integers in the future.
So, the actual question here is what is the better order to prioritize considerations when choosing the type name for 8-bit integer?
Code readability
Since basically in every code having C language roots, primitive type names are a mess. Therefore, probably the most important factor is readability. And by that I mean clear and uniquely identifiable intent of choosing this specific type for this specific integer for the majority of people who would read your code.
So let's take look at those types from an average Objective C programmer point of view who knows little about C language.
unsigned char - what's this??? why char is ever meant to be signed???
uint8_t - ok, unsigned 8 bit integer
UInt8 - hmm, the same as above
Byte - signed or unsigned 8 bit integer
Bytef - what's this? byte-float? what does that 'f' mean?
It's obvious here that unsigned char and Bytef aren't a good choices.
Going further, you can notice another nuisance with Byte type name: you can't say for sure if it represents signed or unsigned integer which could be extremely important when you're trying to understand what is the range of values this integer could hold (-128 .. 127 or 0 .. 256). This is not adding points to code readability, too.
Uniform code style
We're now left with the 2 type names: uint8_t and UInt8. How to choose between them?
Again, looking at them through the eyes of an Objective C programmer, who is using type names like NSInteger, NSUInteger a lot, it looks like much natural when he sees UInt8. uint8_t just looks like a very low-level daunting stuff.
Conclusion
Thus, we eventually are left with the single option - UInt8. Which is clearly identifiable in terms of number of bits, range and looks accustomed. So it's probably the best choice here.
What would be the difference between say doing this?
#define NUMBER 10
and
float number = 10;
In what circumstances should I use one over the other?
#define NUMBER 10
Will create a string replacement that will be executed by the preprocessor (i.e. during compilation).
float number = 10;
Will create a float in the data-segment of your binary and initialize it to 10. I.e. it will have an address and be mutable.
So writing
float a = NUMBER;
will be the same as writing
float a = 10;
whereas writing
float a = number;
will create a memory-access.
As Philipp says, the #define form creates a replacement in your code at the preprocessing stage, before compilation. Because the #define isn't a variable like number, your definition is hard-baked into your executable at compile time. This is desirable if the thing you are repesenting is a truly a constant that doesn't need to calculated or read from somewhere at runtime, and which doesn't change during runtime.
#defines are very useful for making your code more readable. Suppose you were doing physics calculations -- rather than just plonking 0.98f into your code everywhere you need to use the gravitational acceleration constant, you can define it in just one place and it increases your code readability:
#define GRAV_CONSTANT 0.98f
...
float finalVelocity = beginVelocity + GRAV_CONSTANT * time;
EDIT
Surprised to come back and find my answer and see I didn't mention why you shouldn't use #define.
Generally, you want to avoid #define and use constants that are actual types, because #defines don't have scope, and types are beneficial to both IDEs and compilers.
See also this question and accepted answer: What is the best way to create constants in Objective-C
"#Define" is actually a preprocessor macro which is run before the program starts and is valid for the entire program
Float is a data type defined inside a program / block and is valid only within the program / block.