0

Can I test the type of a void pointer? I want to solve this problem:

void log(void *test) {
    if (is a struct) {
        NSLog(test);
    } else {
        printf("%s\n", test);
    }    
}

log(@"This send a struct (NSString)");
log("This send normal string");

There are a easy way to test it?

Rodrigo
  • 11,909
  • 23
  • 68
  • 101
  • 3
    Those tags make this question completely ambiguous. – Griwes Feb 14 '12 at 18:43
  • 2
    Why did you tag these with 3 different languages? Each language has a different way to accomplish this. Also why would you want to write your Log method like that? Instead declare two different log() methods each with a different input type (NSString) and (char*) – Alan Feb 14 '12 at 18:44
  • objective-c is a superset of c. But you can use c++ in Objective-c++.. Maybe the c++ isn't a good choice. – Rodrigo Feb 14 '12 at 18:45
  • 1
    A `void*` is applicable in all 3 languages. I see nothing wrong with the tagging. – TheBuzzSaw Feb 14 '12 at 18:46
  • http://stackoverflow.com/questions/1718412/find-out-type-of-c-void-pointer – Joelmob Feb 14 '12 at 18:46
  • 1
    @Rodrigo, who taught you it? Those are three different languages. Period. TheBuzzSaw - but people tend to mark all of c/c++/obj-c questions with all of the tags (or use just both c and c++ tag - seen question where it was reasonable only once). Obj-c and c++ are based on C, but _C is not their subset!_ – Griwes Feb 14 '12 at 18:46
  • Well all three of them have a void* and within all three of them it has the same meaning. Objective-C's **id** is a different thing. – cli_hlt Feb 14 '12 at 18:46
  • 1
    No, and you can't work out how long an array is from a pointer to its element either, just in case you want to know that too..... – David Heffernan Feb 14 '12 at 18:46
  • Duplicate of:http://stackoverflow.com/questions/1144629/in-objective-c-how-do-i-test-the-object-type – Peter M Feb 14 '12 at 18:47
  • 3
    @TheBuzzSaw: What is the single solution that works across all three languages? – Alan Feb 14 '12 at 18:48
  • Sorry to jump all over you, @Rodrigo. I understand what you are trying to accomplish, but what you are doing is actually wrought with danger. One of the big jumps from C to C++ and Objective-C was adding in type safety, which when used properly cuts down on some major issues. By using void* as a "generic any" type, you are circumventing typesafety. Sometimes it's a necessarily evil to accomplish a task, but in your example, having a generic logging method doesn't appear to be one of those times. – Alan Feb 14 '12 at 18:52

2 Answers2

6

No you cannot test this. A void* is just a memory address where anything (or even nothing) could be stored. It's meaning is entirely implementation dependent and only the original programmer (or the documentation) knows.

cli_hlt
  • 7,072
  • 2
  • 26
  • 22
0

There's really no way to do that kind of detection in a non implementation specific way since when you cast the NSString to a void* you throw away all typing information and convert it to an "untyped pointer to memory".

I'm not sure why you want this kind of functionality, but if it's between two objects, you should use "id" instead of void* since that preserves all type information.

In this specific example, it would probably make a lot more sense to just make "log" an overloaded function and thereby know the type of the parameter compile time.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • If you have a pointer to an _object_, it's possible to find out its class by messaging it (`-class`, `-isKindOfClass:`, `-isMemberOfClass:`) regardless of the type of the pointer itself. One is runtime information, the other is compile-time. – jscs Feb 14 '12 at 19:46
  • @JoshCaswell True, but if you're sure they're all objects, I can't see the reason to cast to a type "lower" than id. When you cast to void* you're more or less deliberately discarding the information that you're dealing with an object. – Joachim Isaksson Feb 14 '12 at 19:55
  • You're right, there's few reasons to do it, and your second paragraph is generally good advice but, for example, I was monkeying around with `NSInvocation` and libffi recently, both of which require objects to be moved around via `void *` occasionally. Other C-style interfaces might require the same. – jscs Feb 14 '12 at 20:01