Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.objective-c > #193 > unrolled thread

Objective C program doesn't compile

Started bymodelling.data@gmail.com
First post2015-11-10 23:32 -0800
Last post2015-11-13 08:19 -0800
Articles 7 — 3 participants

Back to article view | Back to comp.lang.objective-c


Contents

  Objective C program doesn't compile modelling.data@gmail.com - 2015-11-10 23:32 -0800
    Re: Objective C program doesn't compile Don Bruder <dakidd@sonic.net> - 2015-11-11 02:14 -0800
      Re: Objective C program doesn't compile modelling.data@gmail.com - 2015-11-11 06:29 -0800
        Re: Objective C program doesn't compile Don Bruder <dakidd@sonic.net> - 2015-11-11 09:04 -0800
        Re: Objective C program doesn't compile "Pascal J. Bourguignon" <pjb@informatimago.com> - 2015-11-11 19:45 +0100
    Re: Objective C program doesn't compile "Pascal J. Bourguignon" <pjb@informatimago.com> - 2015-11-11 21:03 +0100
      Re: Objective C program doesn't compile modelling.data@gmail.com - 2015-11-13 08:19 -0800

#193 — Objective C program doesn't compile

Frommodelling.data@gmail.com
Date2015-11-10 23:32 -0800
SubjectObjective C program doesn't compile
Message-ID<a5d7b3bf-a215-4dbf-9888-dafcd52fba9f@googlegroups.com>
Hello!

Please, take a look at the program I typed in from the textbook Programming
in C by S. Kochan. I am new to all this, and had no idea how to compile
such programs, the book doesn't cover this topic either. Given I have read 
almost the whole book which is dedicated to C programming, I have tried to use
my Terminal to compile a program. Unfortunately, nothing I tried worked. 

I post my steps, as well as warning messages I get.

I would be grateful for explanation on what I am doing wrong. I work on Mac OS 10.7.5, Xcode 4.6.3, Terminal 2.2.3.

1) I created a file with the command:

touch prog18-2.m

Initially, I have tried usual touch prog18-2.c, then I googled and found 
the information on .m extensions. 

2) Program

/ Program to work with fractions - Objective-C version

#import <stdio.h>
#import <objc/Object.h>

//------ @interface section ---------

@interface Fraction: Object
{
  int numerator;
  int denominator;
}

-(void) set_numerator: (int) n;
-(void) set_denominator: (int) d;
-(void) print;

@end

// ----- @implementation section -------

@implementation Fraction;

// getters

-(int) numerator
{
  return numerator;
}

-(int) denominator
{
  return denominator;
}

//setters

-(void) set_numerator: (int) num
{
   numerator = num;
}

-(void) set_denominator: (int) denom
{
  denominator = denom;
}

//other
-(void) print
{
  printf("The value of the fraction is %i/%i\n", numerator, denominator);
}

@end

//-------- program section -----------

int main(void)
{
  Fraction* my_fract;
  my_fract = [Fraction new];

  [my_fract set_numerator: 1];
  [my_fract set_denominator: 3];

  printf("The numerator is %i, and teh denominator is %i\n", [my_fract numerator], [my_fract denominator]);

  [my_fract print];

  [my_fract free]; //frees the memory that was used by Fraction object

return 0;
}

3) I compiled it with:

gcc -framework Foundation prog18-2.m -o prog18-2

4) The Terminal generated the following:

prog18-2.m: In function 'main':
prog18-2.m:58: warning: 'Fraction' may not respond to '+new'
prog18-2.m:58: warning: (Messages without a matching method signature
prog18-2.m:58: warning: will be assumed to return 'id' and accept
prog18-2.m:58: warning: '...' as arguments.)
prog18-2.m:71: warning: 'Fraction' may not respond to '-free'

Should I use .m or .c for such programs? Am I using a correct compilation
command?

Thank you!

[toc] | [next] | [standalone]


#194

FromDon Bruder <dakidd@sonic.net>
Date2015-11-11 02:14 -0800
Message-ID<n1v492$up$1@dont-email.me>
In reply to#193
In article <a5d7b3bf-a215-4dbf-9888-dafcd52fba9f@googlegroups.com>,
 modelling.data@gmail.com wrote:

> Hello!
> 
> Please, take a look at the program I typed in from the textbook Programming
> in C by S. Kochan. I am new to all this, and had no idea how to compile
> such programs, the book doesn't cover this topic either. Given I have read 
> almost the whole book which is dedicated to C programming, I have tried to 
> use
> my Terminal to compile a program. Unfortunately, nothing I tried worked. 
> 
> I post my steps, as well as warning messages I get.
> 
> I would be grateful for explanation on what I am doing wrong. I work on Mac 
> OS 10.7.5, Xcode 4.6.3, Terminal 2.2.3.
> 
> 1) I created a file with the command:
> 
> touch prog18-2.m
> 
> Initially, I have tried usual touch prog18-2.c, then I googled and found 
> the information on .m extensions. 
> 
> 2) Program
> 
> / Program to work with fractions - Objective-C version
> 
> #import <stdio.h>
> #import <objc/Object.h>
> 
> //------ @interface section ---------
> 
> @interface Fraction: Object
> {
>   int numerator;
>   int denominator;
> }
> 
> -(void) set_numerator: (int) n;
> -(void) set_denominator: (int) d;
> -(void) print;
> 
> @end
> 
> // ----- @implementation section -------
> 
> @implementation Fraction;
> 
> // getters
> 
> -(int) numerator
> {
>   return numerator;
> }
> 
> -(int) denominator
> {
>   return denominator;
> }
> 
> //setters
> 
> -(void) set_numerator: (int) num
> {
>    numerator = num;
> }
> 
> -(void) set_denominator: (int) denom
> {
>   denominator = denom;
> }
> 
> //other
> -(void) print
> {
>   printf("The value of the fraction is %i/%i\n", numerator, denominator);
> }
> 
> @end
> 
> //-------- program section -----------
> 
> int main(void)
> {
>   Fraction* my_fract;
>   my_fract = [Fraction new];
> 
>   [my_fract set_numerator: 1];
>   [my_fract set_denominator: 3];
> 
>   printf("The numerator is %i, and teh denominator is %i\n", [my_fract 
>   numerator], [my_fract denominator]);
> 
>   [my_fract print];
> 
>   [my_fract free]; //frees the memory that was used by Fraction object
> 
> return 0;
> }
> 
> 3) I compiled it with:
> 
> gcc -framework Foundation prog18-2.m -o prog18-2
> 
> 4) The Terminal generated the following:
> 
> prog18-2.m: In function 'main':
> prog18-2.m:58: warning: 'Fraction' may not respond to '+new'
> prog18-2.m:58: warning: (Messages without a matching method signature
> prog18-2.m:58: warning: will be assumed to return 'id' and accept
> prog18-2.m:58: warning: '...' as arguments.)

Means exactly what it says - You're trying to create a new Fraction 
object (via "[Fraction new]") but your Fraction class doesn't contain a 
"new" class method. I see from looking at the code that it also lacks 
any form of "init" or "initWith..." methods, as well. 

> prog18-2.m:71: warning: 'Fraction' may not respond to '-free'

Exactly the same problem - You have no "free" instance method for class 
Fraction.

If that's code you've keyed from a book, the book is garbage, and the 
author needs to be slapped upside the head for being an incompetent 
moron. Especially if you've gotten to chapter 18 and such basic material 
as initializers hasn't been covered well enough for you to know it. I 
assume (perhaps foolishly) that the book you're using has at least 
taught you the difference between a "class" method (such as +new) and an 
"instance" method (such as "-free")? The code you show could be massaged 
into working, but as far as how to write something that at least 
approximates decent Objective-C code, it's a great example of how NOT to 
do it!

> 
> Should I use .m or .c for such programs? Am I using a correct compilation
> command?
> 
> Thank you!

-- 
Security provided by Mssrs Smith and/or Wesson. Brought to you by the letter Q

[toc] | [prev] | [next] | [standalone]


#195

Frommodelling.data@gmail.com
Date2015-11-11 06:29 -0800
Message-ID<96948669-edd2-4771-8e2a-18088313c98b@googlegroups.com>
In reply to#194
<snip>
Don, thank you very much for your reply.

Indeed, I have been told a few times at C group that this book is garbage based
on the code I post from it. I am frustrated now, and have no idea which textbook
to pick up both for C and Objective-C. 

The only thing which I did grab from it, as you mentioned, is the distinction
between class and instance, but that, I believe, is the easiest and trivial 
thing.

I would be grateful for your advice on how to do it the right way - where
shall I read about it? I know there are many sources on the net, but I picked up
this Kochan's one because CS50 course advises it; and now all professionals, 
including you, tell me that the stuff is garbage. I am brand new to
programming, and I am learning on my own asking for help on these two groups.

[toc] | [prev] | [next] | [standalone]


#196

FromDon Bruder <dakidd@sonic.net>
Date2015-11-11 09:04 -0800
Message-ID<n1vsa2$6te$1@dont-email.me>
In reply to#195
In article <96948669-edd2-4771-8e2a-18088313c98b@googlegroups.com>,
 modelling.data@gmail.com wrote:

> <snip>
> Don, thank you very much for your reply.
> 
> Indeed, I have been told a few times at C group that this book is garbage 
> based
> on the code I post from it. I am frustrated now, and have no idea which 
> textbook
> to pick up both for C and Objective-C. 
> 
> The only thing which I did grab from it, as you mentioned, is the distinction
> between class and instance, but that, I believe, is the easiest and trivial 
> thing.
> 
> I would be grateful for your advice on how to do it the right way - where
> shall I read about it? I know there are many sources on the net, but I picked 
> up
> this Kochan's one because CS50 course advises it; and now all professionals, 
> including you, tell me that the stuff is garbage. I am brand new to
> programming, and I am learning on my own asking for help on these two groups.

Professional? Me? Please! Educated hobbyist, at best. 

Fire up XCode (look in your startup drive for the "Developer" folder, 
open it, open "Applications" inside it, and there you'll find  
Xcode.app) - you'll also likely notice a folder with a name real similar 
to (if not actually) "ADC Reference Library" - Might be slightly 
different from OS version to version - You'll want to look through that, 
too) and hit the "help" menu - Apple put out a reasonable-enough set of 
docs for Objective-C that, while not perfect, will at least get you 
started decently.

-- 
Security provided by Mssrs Smith and/or Wesson. Brought to you by the letter Q

[toc] | [prev] | [next] | [standalone]


#198

From"Pascal J. Bourguignon" <pjb@informatimago.com>
Date2015-11-11 19:45 +0100
Message-ID<874mgs4boe.fsf@kuiper.lan.informatimago.com>
In reply to#195
modelling.data@gmail.com writes:

> <snip>
> Don, thank you very much for your reply.
>
> Indeed, I have been told a few times at C group that this book is garbage based
> on the code I post from it. I am frustrated now, and have no idea which textbook
> to pick up both for C and Objective-C. 

Well, a very important book for C would be:

   http://www.amazon.com/gp/product/0201179288?keywords=C%20Traps%20and%20Pitfalls&qid=1447266520&ref_=sr_1_1&sr=8-1

Sorry, I can't advise specifically a good C introductory book.  I would
hope that any of the most recent C books (covering at least c99, if not
c11), would teach good C.  Be careful not to chose a book covering C++
or worse, confusing C with C++.

Similarly, for Objective-C, I learned with the original Objective-C book,
http://www.amazon.com/Object-Oriented-Programming-An-Evolutionary-Approach/dp/0201548348
but Objective-C has evolved a little since, so you might prefer to read
more recent material, notably from Apple.


> The only thing which I did grab from it, as you mentioned, is the distinction
> between class and instance, but that, I believe, is the easiest and trivial 
> thing.
>
> I would be grateful for your advice on how to do it the right way - where
> shall I read about it? I know there are many sources on the net, but I picked up
> this Kochan's one because CS50 course advises it; and now all professionals, 
> including you, tell me that the stuff is garbage. I am brand new to
> programming, and I am learning on my own asking for help on these two groups.

There's nothing wrong fundamentally with your use of +new. It's just
that it was a method that existed in the Object class which was the
(implicit) root of the class hierarchy in older Objective-C.

Nowadays, the Object class is drastically reduced, since it's often
replaced anyways by some other class, such as NSObject.

You can check the header for the Object class. On linux it could be
somewhere like:

/usr/lib/gcc/x86_64-linux-gnu/4.9/include/objc/Object.h

On MacOSX it would be:

/usr/include/objc/Object.h


You can compare them, the gcc class only has:

    @interface Object
    {
      Class isa; /* A pointer to the instance's class structure.  */
    }
    - (Class)class;
    - (BOOL)isEqual: (id)anObject;
    @end

https://gcc.gnu.org/onlinedocs/gcc/Objective-C.html

while MacOSX provides a more complete Object class, including a +new
method.


In any case, you can implement it yourself:

   +(id)new{ return [[self alloc] init]; }

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html
http://readwrite.com/2011/05/14/4-free-e-books-on-objective-c


-- 
__NSObject Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

[toc] | [prev] | [next] | [standalone]


#199

From"Pascal J. Bourguignon" <pjb@informatimago.com>
Date2015-11-11 21:03 +0100
Message-ID<87y4e42tja.fsf@kuiper.lan.informatimago.com>
In reply to#193
modelling.data@gmail.com writes:

> prog18-2.m: In function 'main':
> prog18-2.m:58: warning: 'Fraction' may not respond to '+new'
> prog18-2.m:58: warning: (Messages without a matching method signature
> prog18-2.m:58: warning: will be assumed to return 'id' and accept
> prog18-2.m:58: warning: '...' as arguments.)
> prog18-2.m:71: warning: 'Fraction' may not respond to '-free'

You should use NSObject from Foundation, and dealloc instead of free.

Using Object poses problems; On Linux, gcc Object class is almost empty,
and doesn't have alloc/dealloc or the older new/free.  On MacOSX, Object
is not defined for Objective-C version 2 (if __OBJC2__ is defined), which
is the case by default.

A good way to deal with this problem, would be to define your own root
class, that would inherit from NSObject or Object depending on the
version of the language and where it's compiled on.

    ----(MyObject.h)----------
    #ifdef …
    …
    #endif
    @interface MyObject
    …
    @end
    --------------------------

    ---(Fraction.m)-----------
    #import "MyObject.h"
    @interface Fraction:MyObject
    …
    @end
    --------------------------

This way, you would hide the problem in a single class, MyObject, to
adapt to the various platforms.


> Should I use .m or .c for such programs? Am I using a correct compilation
> command?

.m for Objective-C sources.

----(Fraction.m)------------------------------------------------------------
#import <stdio.h>
#import <Foundation/Foundation.h>
    
//------ @interface section ---------

@interface Fraction:NSObject
{
    int numerator;
    int denominator;
}
-(void)free;
-(void) set_numerator: (int) n;
-(void) set_denominator: (int) d;
-(void) print;

@end

// ----- @implementation section -------

@implementation Fraction;
-(void)free{[self dealloc];}

// getters

-(int) numerator
{
    return numerator;
}

-(int) denominator
{
    return denominator;
}

//setters

-(void) set_numerator: (int) num
{
    numerator = num;
}

-(void) set_denominator: (int) denom
{
    denominator = denom;
}

//other
-(void) print
{
    printf("The value of the fraction is %i/%i\n", numerator, denominator);
}

@end

//-------- program section -----------

int main(void)
{
    Fraction* my_fract;
    my_fract = [Fraction new];

    [my_fract set_numerator: 1];
    [my_fract set_denominator: 3];

    printf("The numerator is %i, and teh denominator is %i\n", [my_fract numerator], [my_fract denominator]);

    [my_fract print];

    [my_fract dealloc]; //frees the memory that was used by Fraction object

    return 0;
}

----(Makefile)------------------------------------------------------------
all:spl-example fraction

.PHONY::run get-dependencies
get-dependencies:
	cd /usr/local/src/ ; git clone git@github.com:cs50/spl.git
	cd /usr/local/src/spl ; make && make install

run:spl-example
	CLASSPATH=/usr/local/lib/spl.jar ./spl-example

LIBS=-lcs -lm -lobjc
CFLAGS=-g3 -O0

spl-example.o:spl-example.m
Fraction.o:Fraction.m 

fraction:Fraction.o 
	gcc $(CFLAGS) $^ -o $@ $(LIBS)

spl-example:spl-example.o
	gcc $(CFLAGS) $^ -o $@ $(LIBS)

clean:
	-rm spl-example fraction
	-rm -rf *.dSYM *.o

--------------------------------------------------------------------------------

[pjb@larissa :0.0 spl-example]$ make
cc -g3 -O0   -c -o spl-example.o spl-example.m
gcc -g3 -O0 spl-example.o -o spl-example -lcs -lm -lobjc
cc -g3 -O0   -c -o Fraction.o Fraction.m
gcc -g3 -O0 Fraction.o -o fraction -lcs -lm -lobjc
[pjb@larissa :0.0 spl-example]$ ./fraction 
The numerator is 1, and teh denominator is 3
The value of the fraction is 1/3
[pjb@larissa :0.0 spl-example]$ 



Some advices:

- in general, you should separate the modules implementing the core
  algorithms, from the modules implementing the user interface.  This
  means, don't do I/O in the classes that model the domain or do
  computations or storage.  

- consider having immutable classes.  Instead of having methods to
  modify the state of the object, initialize the instance with all the
  data, and then don't modify it.  This is particularly true in a class
  like Fraction, since it represent a number and that should be
  immutable.

- similarly, if you want to implement parts of your code in C, and parts
  in Objective-C, I would advise to modularize it very clearly, by
  separating the C code into a purely C module, which can then be used
  from the Objective-C classes.  This allows to re-use the C modules
  from other languages (C++, Lisp, etc).


# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	fr/Makefile
#	fr/MyFraction.h
#	fr/MyFraction.m
#	fr/MyFractionView.h
#	fr/MyFractionView.m
#	fr/MyObject.h
#	fr/MyObject.m
#	fr/fraction.c
#	fr/fraction.h
#	fr/log.txt
#	fr/main.m
#
echo x - fr/Makefile
sed 's/^X//' >fr/Makefile << 'END-of-fr/Makefile'
Xall:run
X
XOBJECTS=main.o MyObject.o MyFractionView.o MyFraction.o fraction.o
XLIBS=-lcs -lobjc -lm
XCFLAGS=-g3 -O0 -Werror -Wall
X
Xfraction.o:fraction.c fraction.h
XMyFraction.o:MyFraction.m MyFraction.h MyObject.h
XMyFractionView.o:MyFractionView.m MyFractionView.h MyFraction.h MyObject.h
XMyObject.o:MyObject.m MyObject.h
Xmain.o:main.m MyFractionView.h MyFraction.h
X
Xfraction:$(OBJECTS)
X	gcc $(CFLAGS) -o $@ $^ $(LIBS)
X
Xclean:
X	-rm *.o fraction
X
Xrun:fraction
X	./fraction
END-of-fr/Makefile
echo x - fr/MyFraction.h
sed 's/^X//' >fr/MyFraction.h << 'END-of-fr/MyFraction.h'
X#import "MyObject.h"
X#import "fraction.h"
X
X@interface MyFraction:MyObject
X{
X    struct fraction* fraction;
X}
X
X-(id)initWithNumerator:(int)num andDenominator:(int)den;
X-(int)numerator;
X-(int)denominator;
X
X@end
X
END-of-fr/MyFraction.h
echo x - fr/MyFraction.m
sed 's/^X//' >fr/MyFraction.m << 'END-of-fr/MyFraction.m'
X#import "MyFraction.h"
X
X@implementation MyFraction
X
X-(id)initWithNumerator:(int)num andDenominator:(int)den{
X    if((self=[super init])){
X        fraction=fraction_new(num,den);
X    }
X    return self;
X}
X
X-(int)numerator{
X    return fraction_num(fraction);
X}
X
X-(int)denominator{
X    return fraction_den(fraction);
X}
X
X@end
X
END-of-fr/MyFraction.m
echo x - fr/MyFractionView.h
sed 's/^X//' >fr/MyFractionView.h << 'END-of-fr/MyFractionView.h'
X#import <stdio.h>
X#import "MyFraction.h"
X
X@interface MyFractionView:MyObject
X{
X    MyFraction* fraction;
X}
X
X-(id)initWithFraction:(MyFraction*)aFraction;
X-(void)displayOnStream:(FILE*)output;
X
X@end
X
END-of-fr/MyFractionView.h
echo x - fr/MyFractionView.m
sed 's/^X//' >fr/MyFractionView.m << 'END-of-fr/MyFractionView.m'
X#import "MyFractionView.h"
X
X@implementation MyFractionView
X
X-(id)initWithFraction:(MyFraction*)aFraction {
X    if((self=[super init])){
X        fraction=aFraction;
X    }
X    return self;
X}
X
X-(void)displayOnStream:(FILE*)output {
X    fprintf(output,"%i/%i",[fraction numerator],[fraction denominator]);
X}
X
X@end
X
END-of-fr/MyFractionView.m
echo x - fr/MyObject.h
sed 's/^X//' >fr/MyObject.h << 'END-of-fr/MyObject.h'
X/* -*- mode:objc -*- */
X#import <Foundation/Foundation.h>
X@interface MyObject:NSObject
X-(void)free;
X@end
X
END-of-fr/MyObject.h
echo x - fr/MyObject.m
sed 's/^X//' >fr/MyObject.m << 'END-of-fr/MyObject.m'
X#import "MyObject.h"
X
X@implementation MyObject
X-(void)free{
X    [self dealloc];
X}
X@end
END-of-fr/MyObject.m
echo x - fr/fraction.c
sed 's/^X//' >fr/fraction.c << 'END-of-fr/fraction.c'
X#include "fraction.h"
X#include <libc.h>
X
Xtypedef struct fraction {
X    int num;
X    int den;
X} fraction;
X
Xfraction* fraction_new(int num,int den){
X    if(den==0){
X        return NULL;
X    }
X    fraction* fr=malloc(sizeof(*fr));
X    if(fr){
X        fr->num=num;
X        fr->den=den;
X    }
X    return fr;
X}
X
X
X
Xint fraction_num(fraction* fr){
X    if(fr){
X        return fr->num;
X    }else{
X        return 0;
X    }
X}
X
Xint fraction_den(fraction* fr){
X    if(fr){
X        return fr->den;
X    }else{
X        return 1;
X    }
X}
X
Xvoid fraction_free(fraction* fr){
X    if(fr){
X        free(fr);
X    }
X}
X
END-of-fr/fraction.c
echo x - fr/fraction.h
sed 's/^X//' >fr/fraction.h << 'END-of-fr/fraction.h'
X#ifndef __fraction__
X#define __fraction__
X
Xextern struct fraction* fraction_new(int num,int den);
Xextern int fraction_num(struct fraction* fr);
Xextern int fraction_den(struct fraction* fr);
Xextern void fraction_free(struct fraction* fr);
X
X#endif
END-of-fr/fraction.h
echo x - fr/log.txt
sed 's/^X//' >fr/log.txt << 'END-of-fr/log.txt'
X-*- mode: compilation; default-directory: "~/src/spl-example/fr/" -*-
XCompilation started at Wed Nov 11 20:59:45
X
Xmake -k clean all
Xrm *.o fraction
Xcc -g3 -O0 -Werror -Wall   -c -o main.o main.m
Xcc -g3 -O0 -Werror -Wall   -c -o MyObject.o MyObject.m
Xcc -g3 -O0 -Werror -Wall   -c -o MyFractionView.o MyFractionView.m
Xcc -g3 -O0 -Werror -Wall   -c -o MyFraction.o MyFraction.m
Xcc -g3 -O0 -Werror -Wall   -c -o fraction.o fraction.c
Xgcc -g3 -O0 -Werror -Wall -o fraction main.o MyObject.o MyFractionView.o MyFraction.o fraction.o -lcs -lobjc -lm
X./fraction
XThe numerator is 1, and the denominator is 3
XThe value of the fraction is 1/3
X
XCompilation finished at Wed Nov 11 20:59:46
END-of-fr/log.txt
echo x - fr/main.m
sed 's/^X//' >fr/main.m << 'END-of-fr/main.m'
X#import "MyFraction.h"
X#import "MyFractionView.h"
X
Xint main(int argc,char** argv){
X    MyFraction* fraction=[[MyFraction alloc]initWithNumerator:1
X                                               andDenominator:3];
X    MyFractionView* view=[[MyFractionView alloc]initWithFraction:fraction];
X
X    printf("The numerator is %i, and the denominator is %i\n",
X           [fraction numerator], [fraction denominator]);
X    printf("The value of the fraction is ");
X    [view displayOnStream:stdout];
X    printf("\n");
X    return 0;
X}
END-of-fr/main.m
exit



-- 
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

[toc] | [prev] | [next] | [standalone]


#200

Frommodelling.data@gmail.com
Date2015-11-13 08:19 -0800
Message-ID<5ac234d8-a01d-45fd-8e66-a95f332dd1d1@googlegroups.com>
In reply to#199
On Thursday, November 12, 2015 at 12:03:08 AM UTC+4, Pascal J. Bourguignon wrote:
> modelling.data@gmail.com writes:
> 
> > prog18-2.m: In function 'main':
> > prog18-2.m:58: warning: 'Fraction' may not respond to '+new'
> > prog18-2.m:58: warning: (Messages without a matching method signature
> > prog18-2.m:58: warning: will be assumed to return 'id' and accept
> > prog18-2.m:58: warning: '...' as arguments.)
> > prog18-2.m:71: warning: 'Fraction' may not respond to '-free'
> 
> You should use NSObject from Foundation, and dealloc instead of free.
> 
> Using Object poses problems; On Linux, gcc Object class is almost empty,
> and doesn't have alloc/dealloc or the older new/free.  On MacOSX, Object
> is not defined for Objective-C version 2 (if __OBJC2__ is defined), which
> is the case by default.
> 
> A good way to deal with this problem, would be to define your own root
> class, that would inherit from NSObject or Object depending on the
> version of the language and where it's compiled on.
> 
>     ----(MyObject.h)----------
>     #ifdef ...
>     ...
>     #endif
>     @interface MyObject
>     ...
>     @end
>     --------------------------
> 
>     ---(Fraction.m)-----------
>     #import "MyObject.h"
>     @interface Fraction:MyObject
>     ...
>     @end
>     --------------------------
> 
> This way, you would hide the problem in a single class, MyObject, to
> adapt to the various platforms.
> 
> 
> > Should I use .m or .c for such programs? Am I using a correct compilation
> > command?
> 
> .m for Objective-C sources.
> 
> ----(Fraction.m)------------------------------------------------------------
> #import <stdio.h>
> #import <Foundation/Foundation.h>
>     
> //------ @interface section ---------
> 
> @interface Fraction:NSObject
> {
>     int numerator;
>     int denominator;
> }
> -(void)free;
> -(void) set_numerator: (int) n;
> -(void) set_denominator: (int) d;
> -(void) print;
> 
> @end
> 
> // ----- @implementation section -------
> 
> @implementation Fraction;
> -(void)free{[self dealloc];}
> 
> // getters
> 
> -(int) numerator
> {
>     return numerator;
> }
> 
> -(int) denominator
> {
>     return denominator;
> }
> 
> //setters
> 
> -(void) set_numerator: (int) num
> {
>     numerator = num;
> }
> 
> -(void) set_denominator: (int) denom
> {
>     denominator = denom;
> }
> 
> //other
> -(void) print
> {
>     printf("The value of the fraction is %i/%i\n", numerator, denominator);
> }
> 
> @end
> 
> //-------- program section -----------
> 
> int main(void)
> {
>     Fraction* my_fract;
>     my_fract = [Fraction new];
> 
>     [my_fract set_numerator: 1];
>     [my_fract set_denominator: 3];
> 
>     printf("The numerator is %i, and teh denominator is %i\n", [my_fract numerator], [my_fract denominator]);
> 
>     [my_fract print];
> 
>     [my_fract dealloc]; //frees the memory that was used by Fraction object
> 
>     return 0;
> }
> 
> ----(Makefile)------------------------------------------------------------
> all:spl-example fraction
> 
> .PHONY::run get-dependencies
> get-dependencies:
> 	cd /usr/local/src/ ; git clone git@github.com:cs50/spl.git
> 	cd /usr/local/src/spl ; make && make install
> 
> run:spl-example
> 	CLASSPATH=/usr/local/lib/spl.jar ./spl-example
> 
> LIBS=-lcs -lm -lobjc
> CFLAGS=-g3 -O0
> 
> spl-example.o:spl-example.m
> Fraction.o:Fraction.m 
> 
> fraction:Fraction.o 
> 	gcc $(CFLAGS) $^ -o $@ $(LIBS)
> 
> spl-example:spl-example.o
> 	gcc $(CFLAGS) $^ -o $@ $(LIBS)
> 
> clean:
> 	-rm spl-example fraction
> 	-rm -rf *.dSYM *.o
> 
> --------------------------------------------------------------------------------
> 
> [pjb@larissa :0.0 spl-example]$ make
> cc -g3 -O0   -c -o spl-example.o spl-example.m
> gcc -g3 -O0 spl-example.o -o spl-example -lcs -lm -lobjc
> cc -g3 -O0   -c -o Fraction.o Fraction.m
> gcc -g3 -O0 Fraction.o -o fraction -lcs -lm -lobjc
> [pjb@larissa :0.0 spl-example]$ ./fraction 
> The numerator is 1, and teh denominator is 3
> The value of the fraction is 1/3
> [pjb@larissa :0.0 spl-example]$ 
> 
> 
> 
> Some advices:
> 
> - in general, you should separate the modules implementing the core
>   algorithms, from the modules implementing the user interface.  This
>   means, don't do I/O in the classes that model the domain or do
>   computations or storage.  
> 
> - consider having immutable classes.  Instead of having methods to
>   modify the state of the object, initialize the instance with all the
>   data, and then don't modify it.  This is particularly true in a class
>   like Fraction, since it represent a number and that should be
>   immutable.
> 
> - similarly, if you want to implement parts of your code in C, and parts
>   in Objective-C, I would advise to modularize it very clearly, by
>   separating the C code into a purely C module, which can then be used
>   from the Objective-C classes.  This allows to re-use the C modules
>   from other languages (C++, Lisp, etc).
> 
> 
> # This is a shell archive.  Save it in a file, remove anything before
> # this line, and then unpack it by entering "sh file".  Note, it may
> # create directories; files and directories will be owned by you and
> # have default permissions.
> #
> # This archive contains:
> #
> #	fr/Makefile
> #	fr/MyFraction.h
> #	fr/MyFraction.m
> #	fr/MyFractionView.h
> #	fr/MyFractionView.m
> #	fr/MyObject.h
> #	fr/MyObject.m
> #	fr/fraction.c
> #	fr/fraction.h
> #	fr/log.txt
> #	fr/main.m
> #
> echo x - fr/Makefile
> sed 's/^X//' >fr/Makefile << 'END-of-fr/Makefile'
> Xall:run
> X
> XOBJECTS=main.o MyObject.o MyFractionView.o MyFraction.o fraction.o
> XLIBS=-lcs -lobjc -lm
> XCFLAGS=-g3 -O0 -Werror -Wall
> X
> Xfraction.o:fraction.c fraction.h
> XMyFraction.o:MyFraction.m MyFraction.h MyObject.h
> XMyFractionView.o:MyFractionView.m MyFractionView.h MyFraction.h MyObject.h
> XMyObject.o:MyObject.m MyObject.h
> Xmain.o:main.m MyFractionView.h MyFraction.h
> X
> Xfraction:$(OBJECTS)
> X	gcc $(CFLAGS) -o $@ $^ $(LIBS)
> X
> Xclean:
> X	-rm *.o fraction
> X
> Xrun:fraction
> X	./fraction
> END-of-fr/Makefile
> echo x - fr/MyFraction.h
> sed 's/^X//' >fr/MyFraction.h << 'END-of-fr/MyFraction.h'
> X#import "MyObject.h"
> X#import "fraction.h"
> X
> X@interface MyFraction:MyObject
> X{
> X    struct fraction* fraction;
> X}
> X
> X-(id)initWithNumerator:(int)num andDenominator:(int)den;
> X-(int)numerator;
> X-(int)denominator;
> X
> X@end
> X
> END-of-fr/MyFraction.h
> echo x - fr/MyFraction.m
> sed 's/^X//' >fr/MyFraction.m << 'END-of-fr/MyFraction.m'
> X#import "MyFraction.h"
> X
> X@implementation MyFraction
> X
> X-(id)initWithNumerator:(int)num andDenominator:(int)den{
> X    if((self=[super init])){
> X        fraction=fraction_new(num,den);
> X    }
> X    return self;
> X}
> X
> X-(int)numerator{
> X    return fraction_num(fraction);
> X}
> X
> X-(int)denominator{
> X    return fraction_den(fraction);
> X}
> X
> X@end
> X
> END-of-fr/MyFraction.m
> echo x - fr/MyFractionView.h
> sed 's/^X//' >fr/MyFractionView.h << 'END-of-fr/MyFractionView.h'
> X#import <stdio.h>
> X#import "MyFraction.h"
> X
> X@interface MyFractionView:MyObject
> X{
> X    MyFraction* fraction;
> X}
> X
> X-(id)initWithFraction:(MyFraction*)aFraction;
> X-(void)displayOnStream:(FILE*)output;
> X
> X@end
> X
> END-of-fr/MyFractionView.h
> echo x - fr/MyFractionView.m
> sed 's/^X//' >fr/MyFractionView.m << 'END-of-fr/MyFractionView.m'
> X#import "MyFractionView.h"
> X
> X@implementation MyFractionView
> X
> X-(id)initWithFraction:(MyFraction*)aFraction {
> X    if((self=[super init])){
> X        fraction=aFraction;
> X    }
> X    return self;
> X}
> X
> X-(void)displayOnStream:(FILE*)output {
> X    fprintf(output,"%i/%i",[fraction numerator],[fraction denominator]);
> X}
> X
> X@end
> X
> END-of-fr/MyFractionView.m
> echo x - fr/MyObject.h
> sed 's/^X//' >fr/MyObject.h << 'END-of-fr/MyObject.h'
> X/* -*- mode:objc -*- */
> X#import <Foundation/Foundation.h>
> X@interface MyObject:NSObject
> X-(void)free;
> X@end
> X
> END-of-fr/MyObject.h
> echo x - fr/MyObject.m
> sed 's/^X//' >fr/MyObject.m << 'END-of-fr/MyObject.m'
> X#import "MyObject.h"
> X
> X@implementation MyObject
> X-(void)free{
> X    [self dealloc];
> X}
> X@end
> END-of-fr/MyObject.m
> echo x - fr/fraction.c
> sed 's/^X//' >fr/fraction.c << 'END-of-fr/fraction.c'
> X#include "fraction.h"
> X#include <libc.h>
> X
> Xtypedef struct fraction {
> X    int num;
> X    int den;
> X} fraction;
> X
> Xfraction* fraction_new(int num,int den){
> X    if(den==0){
> X        return NULL;
> X    }
> X    fraction* fr=malloc(sizeof(*fr));
> X    if(fr){
> X        fr->num=num;
> X        fr->den=den;
> X    }
> X    return fr;
> X}
> X
> X
> X
> Xint fraction_num(fraction* fr){
> X    if(fr){
> X        return fr->num;
> X    }else{
> X        return 0;
> X    }
> X}
> X
> Xint fraction_den(fraction* fr){
> X    if(fr){
> X        return fr->den;
> X    }else{
> X        return 1;
> X    }
> X}
> X
> Xvoid fraction_free(fraction* fr){
> X    if(fr){
> X        free(fr);
> X    }
> X}
> X
> END-of-fr/fraction.c
> echo x - fr/fraction.h
> sed 's/^X//' >fr/fraction.h << 'END-of-fr/fraction.h'
> X#ifndef __fraction__
> X#define __fraction__
> X
> Xextern struct fraction* fraction_new(int num,int den);
> Xextern int fraction_num(struct fraction* fr);
> Xextern int fraction_den(struct fraction* fr);
> Xextern void fraction_free(struct fraction* fr);
> X
> X#endif
> END-of-fr/fraction.h
> echo x - fr/log.txt
> sed 's/^X//' >fr/log.txt << 'END-of-fr/log.txt'
> X-*- mode: compilation; default-directory: "~/src/spl-example/fr/" -*-
> XCompilation started at Wed Nov 11 20:59:45
> X
> Xmake -k clean all
> Xrm *.o fraction
> Xcc -g3 -O0 -Werror -Wall   -c -o main.o main.m
> Xcc -g3 -O0 -Werror -Wall   -c -o MyObject.o MyObject.m
> Xcc -g3 -O0 -Werror -Wall   -c -o MyFractionView.o MyFractionView.m
> Xcc -g3 -O0 -Werror -Wall   -c -o MyFraction.o MyFraction.m
> Xcc -g3 -O0 -Werror -Wall   -c -o fraction.o fraction.c
> Xgcc -g3 -O0 -Werror -Wall -o fraction main.o MyObject.o MyFractionView.o MyFraction.o fraction.o -lcs -lobjc -lm
> X./fraction
> XThe numerator is 1, and the denominator is 3
> XThe value of the fraction is 1/3
> X
> XCompilation finished at Wed Nov 11 20:59:46
> END-of-fr/log.txt
> echo x - fr/main.m
> sed 's/^X//' >fr/main.m << 'END-of-fr/main.m'
> X#import "MyFraction.h"
> X#import "MyFractionView.h"
> X
> Xint main(int argc,char** argv){
> X    MyFraction* fraction=[[MyFraction alloc]initWithNumerator:1
> X                                               andDenominator:3];
> X    MyFractionView* view=[[MyFractionView alloc]initWithFraction:fraction];
> X
> X    printf("The numerator is %i, and the denominator is %i\n",
> X           [fraction numerator], [fraction denominator]);
> X    printf("The value of the fraction is ");
> X    [view displayOnStream:stdout];
> X    printf("\n");
> X    return 0;
> X}
> END-of-fr/main.m
> exit
> 
> 
> 
> -- 
> __Pascal Bourguignon__                 http://www.informatimago.com/
> "The factory of the future will have only two employees, a man and a
> dog. The man will be there to feed the dog. The dog will be there to
> keep the man from touching the equipment." -- Carl Bass CEO Autodesk

Thank you very much for your detailed answer and your 
help, and also for advice on books. Thank you!

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.objective-c


csiph-web