

macで下記C/C++のコードを書きましたが、下記エラーでコンパイルできません。

**intarray.cpp**

[code]

    #include<stddef.h>
    #include<stdlib.h>
    #include<stdio.h>
    
    
    struct IntArray {
      int *elems;
      size_t numElems;
    };
    
    void IA_init(IntArray *object);
    void IA_cleanup(IntArray *object);
    void IA_setSize(IntArray *object, size_t value);
    size_t IA_getSize(IntArray *object);
    void IA_setElem(IntArray *object, size_t index, int value);
    int IA_getElem(IntArray *object, size_t index);
    
    
    void IA_init(IntArray *object, size_t value){
      object->numElems = 0;
      object->elems = 0;
    }
    
    void IA_cleanup(IntArray *object){
      free(object->elems);
    }
    
    void IA_setSize(IntArray *object, size_t value){
      if(object->elems != 0) free(object->elems);
      object->numElems = value;
      object->elems = (int *)malloc(value * sizeof(int));
    }
    
    void IA_setElem(IntArray *object, size_t value, int index){
      if(index >= object->numElems) {
        printf("bad index");
        return;
      }
      object->elems[index] = value;
    }
    
    int IA_getElem(IntArray *object, size_t index){
      if(index >= object->numElems){
        printf("bad index");
        return 0;
      }
      return object->elems[index];
    }
    
    int main(){
      IntArray powersOf2;
      IA_init(&powersOf2);
      IA_setSize(&powersOf2, 8);
      IA_setElem(&powersOf2, 0, 1);
      int i;
      for(i=1; i<8; i++){
        IA_setElem(&powersOf2, i, 2 * IA_getElem(&powersOf2, i-1));
      }
      IA_cleanup(&powersOf2);
    
      return 0;
    }
    
[/code]

**コマンド**

[code]

    g++ -v intarray.cpp -o intarray
    
[/code]

**エラー**

[code]

    Apple LLVM version 7.0.2 (clang-700.1.81)
    Target: x86_64-apple-darwin15.2.0
    Thread model: posix
     "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.11.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name intarray.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 253.9 -v -dwarf-column-info -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.0.2 -stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /Users/username/workspaces/c_plus_plus_workspace/class -ferror-limit 19 -fmessage-length 144 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.11.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/2z/x8jb59gs1lz7n1hhbhk_st8c0000gn/T/intarray-f42434.o -x c++ intarray.cpp
    clang -cc1 version 7.0.2 based upon LLVM 3.7.0svn default target x86_64-apple-darwin15.2.0
    ignoring nonexistent directory "/usr/include/c++/v1"
    #include "..." search starts here:
    #include <...> search starts here:
     /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1
     /usr/local/include
     /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.0.2/include
     /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
     /usr/include
     /System/Library/Frameworks (framework directory)
     /Library/Frameworks (framework directory)
    End of search list.
     "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.11.0 -o intarray /var/folders/2z/x8jb59gs1lz7n1hhbhk_st8c0000gn/T/intarray-f42434.o -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.0.2/lib/darwin/libclang_rt.osx.a
    Undefined symbols for architecture x86_64:
      "IA_init(IntArray*)", referenced from:
          _main in intarray-f42434.o
         (maybe you meant: __Z7IA_initP8IntArraym)
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
[/code]

検索すると幾つか同じエラーになっているという報告を見られましたが、解決方法を試しても解決しませんでした。

しかし、下記コードはコンパイルできました。

hello.cpp

[code]

    #include<stdio.h>
    
    int main(){
      printf("Hello, world");
      return 0;
    }
    
[/code]

hello.cpp

[code]

    #include<iostream>
    
    int main(){
      std::cout << "Hello, world" << "\n";
      return 0;
    }
    
[/code]

なぜ上記のコードはコンパイルできないのでしょうか。

**実行環境**

Mac El Captan bash

**追記**

ちなみに下記コードでもエラーが出ました。

**intarray2.h**

[code]

    #include<stddef.h>
    #include<stdio.h>
    #include<stdlib.h>
    
    class IntArray{
      public:
        void init();
        void cleanup();
        void setSize(size_t value);
        size_t getSize();
        void setElem(size_t index, int value);
        int getElem(size_t index);
    
      private:
        int *elems;
        size_t numElems;
    };
    
[/code]

**intarray2.cpp**

[code]

    #include<stddef.h>
    #include<stdio.h>
    #include<stdlib.h>
    
    class IntArray{
      void IntArray::init(){
        this->numElems = 0;
        this->elems = 0;
      }
    
      void IntArray::cleanup(){
        this->numElems = 0;
        free(this->elems);
      }
    
      void setSize(size_t, value){
       if(this->elems != 0) free(this->elems);
       this->numElems = value;
       this->elems = (int *) malloc(value * sizeof(int));
      }
    
      void IntArray::setElem(size_t valuem, int index){
        if(index >= this->numElems){
          printf("bad index");
          return;
        }
        this->elems[index] = value;
      }
    
      int IntArray::getElem(size_t index){
        if(index >= this->numElems){
          printf("bad index");
          return 1;
        }
        return this->elems[index];
      }
    }
    
[/code]

**main.cpp**

[code]

    #include "IntArray2.h"
    
    int main(){
      IntArray powerOf2;
      powerOf2.init();
      powerOf2.setSize(8);
      int i;
      for(i=0;i<8;i++){
        powerOf2.setElem(i, 2 * powerOf2.getElem(i-1));
      }
      powerOf2.cleanup();
      return 0;
    }
    
[/code]

**エラー**

[code]

    Undefined symbols for architecture x86_64:
      "IntArray::init()", referenced from:
          _main in main-d429d9.o
      "IntArray::cleanup()", referenced from:
          _main in main-d429d9.o
      "IntArray::getElem(unsigned long)", referenced from:
          _main in main-d429d9.o
      "IntArray::setElem(unsigned long, int)", referenced from:
          _main in main-d429d9.o
      "IntArray::setSize(unsigned long)", referenced from:
          _main in main-d429d9.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
[/code]


CC BY-SA 3.0
2016-01-09T01:12:38.697
20765
2016-01-09T22:53:16.777
2016-01-09T22:53:16.777
5044
7232
question
c++
macでc/c++をコンパイルできない。


in the C code, all references to `IntArray` (other than the struct definition)
must be `struct IntArray`. This will fix most of the compiler raised warnings.

Then the prototype for `IA_init()` and the call to `IA_init()` do not match
the actual function signature. The actual function has 2 parameters, which the
call and the prototype only have a single parameter.

this function: `void IA_setElem(struct IntArray *object, size_t value, int
index){` is passing a `size_t` but the receiving field in the IntArray is of
type `int`

this line: `IA_setElem(&powersOf2, i, 2 * IA_getElem(&powersOf2, i-1));` is
passing the `int i` value to two different functions where those functions are
expecting a `size_t` rather than a `int`.

in function: IA_init(), setting the int pointer field: `elems` to 0 will work
in this scenario, however, the assignment is expecting a pointer, not an
integer, suggest using: `object->elems = NULL;`

When calling `malloc()` in c, do not cast the returned value, its' type is
`void*` which can be assigned to any pointer. Casting just clutters the code,
makes understanding, debug, and maintenance much more difficult.

The code contains some 'magic' numbers. (like 8) 'magic' numbers make the code
much more difficult to understand, debug, maintain. Suggest using #define
statements to give the magic numbers meaningful names,. then using those
meaningful names throughout the code.

regarding this line: `if(index >= object->numElems) {`. It causes the compiler
to raise a warning about a comparison between signed (int) and unsigned
(size_t) values. suggest passing the `index` parameter as a `size_t` rather
than a `int`


CC BY-SA 3.0
2016-01-09T05:14:21.423
20773
2016-01-09T05:14:21.423
13950
20765
answer


一つ目の例の修正点

Ｃ形式のヘッダでなく以下を使う

[code]

    #include <cstdio>
    #include <cstdlib>
    
[/code]

`IA_init` が既に指摘されているようにプロトタイプと実装が異なっています  
引数を一致させます。

[code]

    void IA_init(IntArray *object){
      object->numElems = 0;
      object->elems = 0;
    }
    
[/code]

* * *

２つめの例の修正点（既に指摘されているクラス定義で囲まないは省略）

`void setSize(size_t, value){`  
`,` が余計です。クラス修飾がありません。  
以下のように変更します。  
`void IntArray::setSize(size_t value){`

`void IntArray::setElem(size_t valuem, int index){`  
`valuem` は `value`の間違いだと思われます。  
以下のように変更します。  
`void IntArray::setElem(size_t value, int index){`

取りあえず、これでコンパイルできるようになると思います。


CC BY-SA 3.0
2016-01-09T09:02:44.427
20778
2016-01-09T09:16:59.253
2016-01-09T09:16:59.253
5044
5044
20765
answer

[code]

    #include<stddef.h>
    #include<stdlib.h>
    #include<stdio.h>
    
    
    struct IntArray
    {
      size_t *elems;
      size_t numElems;
    };
    
    #if 0
    void IA_init(IntArray *object);
    void IA_cleanup(IntArray *object);
    void IA_setSize(IntArray *object, size_t value);
    size_t IA_getSize(IntArray *object);
    void IA_setElem(IntArray *object, size_t index, int value);
    int IA_getElem(IntArray *object, size_t index);
    #endif
    
    //void IA_init(IntArray *object, size_t value){
    void IA_init(struct IntArray *object) {
    
      object->numElems = 0;
      object->elems = NULL;
    }
    
    void IA_cleanup(struct IntArray *object){
      free(object->elems);
    }
    
    void IA_setSize(struct IntArray *object, size_t value){
      if(object->elems != 0) free(object->elems);
      object->numElems = value;
    
      object->elems = malloc(value * sizeof(size_t));
      if( NULL == object->elems )
      { // then malloc failed
          perror( "malloc failed" );
          exit( EXIT_FAILURE );
      }
      // implied else, malloc successful
    }
    
    void IA_setElem(struct IntArray *object, size_t value, size_t index){
      if(index >= object->numElems) {
        printf("bad index");
        return;
      }
      object->elems[index] = value;
    }
    
    size_t IA_getElem(struct IntArray *object, size_t index){
      if(index >= object->numElems){
        printf("bad index");
        return 0;
      }
      return object->elems[index];
    }
    
    int main( void ){
      struct IntArray powersOf2;
      IA_init(&powersOf2);
      IA_setSize(&powersOf2, 8);
      IA_setElem(&powersOf2, 0, 1);
      size_t i;
    
      for(i=1; i<8; i++){
        IA_setElem(&powersOf2, i, 2 * IA_getElem(&powersOf2, i-1));
      }
      IA_cleanup(&powersOf2);
    
      return 0;
    }
    
[/code]


CC BY-SA 3.0
2016-01-09T14:42:30.660
20787
2016-01-09T14:42:30.660
13950
20765
answer