Anand Sunderraman
Anand Sunderraman

Reputation: 8148

Objective C compilation with gcc 4.6.2

I am trying to learn objective c on windows. My program compiles with warnings

My code is

#include <objc/Object.h>

@interface Greeter:Object
{
  /* This is left empty on purpose:
   ** Normally instance variables would be declared here,
   ** but these are not used in our example.
   */
}

- (void)greet;

@end

#include <stdio.h>

@implementation Greeter

- (void)greet
{
    printf("Hello, World!\n");
}

@end

#include <stdlib.h>

int main(void)
{
    id myGreeter;
    myGreeter=[[Greeter alloc] init];
    [myGreeter greet];
    [myGreeter release];
    return EXIT_SUCCESS;
}

I compile my program on GNUStep using the following command

 gcc -o Greeter Greeter.m -I /GNUstep/System/Library/Headers -L /GNUstep/System/Libra
 /Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString

I get the following warnings on compilation

: 'Greeter' may not respond to '+alloc' [enabled by default]
: (Messages without a matching method signature [enabled by default]
: will be assumed to return 'id' and accept [enabled by default]
: '...' as arguments.) [enabled by default]
: no '-init' method found [enabled by default]
: no '-release' method found [enabled by default]

And so when I run my executable the object does not get instantiated.

I am using gcc from MinGW where gcc version is 4.6.2

--UPDATE---

The program runs fine when I extend from NSObject instead of Object

--UPDATE 2 ----

My Object.h looks like

#include <objc/runtime.h>

@interface Object
{
    Class isa;
}
@end

--UPDATE 3 ----

I have modified my code as follows. It compiles fine, but I am not sure if this is the right way to go about things

@interface Greeter
{
  /* This is left empty on purpose:
   ** Normally instance variables would be declared here,
   ** but these are not used in our example.
   */
}

- (void)greet;

+ (id)alloc;
- (id)init;
- release;

@end

#include <stdio.h>

@implementation Greeter

- (void)greet
{
    printf("Hello, World!\n");
}

+ (id)alloc
  {
    printf("Object created");
    return self;
  }

- (id)init
  {
    printf("Object instantiated");
    return self;
  }

- release {}

@end

#include <stdlib.h>

int main(void)
{
    id myGreeter;
    myGreeter=[[Greeter alloc] init];
    [myGreeter greet];
    [myGreeter release];
    return EXIT_SUCCESS;
}

Upvotes: 3

Views: 2266

Answers (5)

Francesco
Francesco

Reputation: 1848

Have you tried with [Greeter new]; ? Open Object.h and take a look at the methods defined in the Object class...

EDIT: To implement the alloc, retain and release you have to call the objc runtime. So.. I think you have to write something like this:

@interface RootObject : Object
+ (id)alloc;
- (id)init;
- (id)retain;
- (void)release;
@end


@implementation RootObject
{
    unsigned int retainCount;
}

+ (id)alloc
{
    id myObj = class_createInstance([self class], 0);
    /* FOR NEWBIES this works for GCC (default ubuntu 20.04 LTS)
    id myObj = class_createInstance(self, 0);
    */ 
    return myObj;
}
- (id)init
{
    retainCount = 1;
    return self;
}
- (id)retain
{
    retainCount++;
    return self;
}
- (void)release
{
    retainCount--;
    if (retainCount == 0) {
        object_dispose(self);
    }
}

@end

And then you can subclass RootObject.

Upvotes: 0

Chris Reid
Chris Reid

Reputation: 488

What I did was to install gcc-4.6 alongside the 4.7 that came with the linux system. It seems to work, as it has a compatability layer for older code. In my basic Makefile I specify

>     CC=gcc-4.6
>     LIBS=-lobjc -lpthread
>     
>     all:       objc-test.m
>         $(CC)  -o objctest  objc-test.m $(LIBS)

There is nothing "wrong" with using and older version of gcc. The new 4.7 version has gutted the objc system so it is not a stand-alone compilation suite. That sucks. I imagine there is some reason, possibly a political one, possibly just that it is difficult to make one compiler do it all for everyone. I have successfully made objc programs with gnustep in X86_64 Linux with gcc 4.7.3 after banging out failure for two days the old way.

It involves a bunch of setup:

setting up the environment variables with

source /usr/share/GNUstep/Makefiles/GNUstep.sh

and conforming to their build system.
A Basic GNUmakefile:

include $(GNUSTEP_MAKEFILES)/common.make

TOOL_NAME = test

test_OBJC_FILES = main.m  

include $(GNUSTEP_MAKEFILES)/tool.make

for

main.m:

#import <Foundation/Foundation.h>

int
main (void)
{ 
  NSLog (@"Executing");
  return 0;
}

running

gs_make

builds the binary in a subdir obj.

It is actually quite frustrating to fight with the build system like that and have to spend hours teasing out tidbitsfrom docs just to get basic functionality from such a great compiler. I hope they fix it in coming iterations.

Upvotes: 0

bbum
bbum

Reputation: 162722

Unless you are studying the history of Objective-C, trying to learn the language based on the Object class is a complete waste of time. The Object class was last used commonly as a root class in pre-1994 NEXTSTEP.

If your goal is to learn pre-1994 Objective-C, then state that because, if so, the answers you have so far are entirely wrong. Even if the goal is to go with modern patterns, the answers are more along the lines of How do I recreate NSObject? than anything else. Note that if that is your goal.... well... go for it! Pre-1994 Objective-C was kinda like OOP macro-assembly and, through that, there was a ton of power through at the metal simplicity.

For example, you say that "I have modified my code as follows. It compiles fine, but I am not sure if this is the right way to go about things".

That code compiles, but -- no -- it doesn't work. Not at all. For starters, the +alloc method doesn't actually allocate anything. Nor does the Greeter class implement near enough functionality to act anything like an NSObject.

If your goal is to learn something akin to modern Objective-C and use Windows to do so, the best possible way would likely to be to install the GNUStep toolchain. With that, at least, you would be programming against an NSObject rooted set of APIs akin to modern Cocoa (and, to a lesser extent, iOS).

If your goal is to learn truly modern Objective-C, you'll want an environment that can run the latest versions of LLVM, at the very least. And, of course, if you want to write Objective-C based iOS or Mac OS X apps, you'll want a Mac running Lion.

Upvotes: 18

jacekmigacz
jacekmigacz

Reputation: 789

Import Foundation.

#import <Foundation/Foundation.h>

Extend NSObject instead of Object.

@interface Greeter : NSObject

Upvotes: 2

dreamlax
dreamlax

Reputation: 95405

From memory, the Object class does not implement retain counts, so it wouldn't have release, it'll have free or some other method. It should have +alloc and -init though. Since there's no “Objective-C standard”, you'll have to open up your objc/Object.h and see exactly what it offers.

Note that on GCC 4.6.2, objc/Object.h actually includes objc/deprecated/Object.h, meaning support for Object as a class may be fairly limited. If it doesn't include it, try including it yourself:

#import <objc/deprecated/Object.h>

Upvotes: 3

Related Questions