Multiple definition of main ошибка code blocks

Your privacy

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

otreblA_SNAKE_[ITA]

Hi there guys,
I’m studying C++ with Deitel «C++ How To Program» and I’ve done a small «gradebook» program. However I’ve a problem: when I try tu build&run my program I’ve an error:

C:UsersAlbertoAppDataLocalTempccSdybij.o:main.cpp|| multiple definition of `main’|
objDebugmain.o:C:UsersAlbertoDocumentsProgetti C++ CodeBlocksConsoleApplication24main.cpp|10|first defined here|
||=== Build finished: 2 errors, 0 warnings ===|

Here’s my simple program:

gradebook.h

#include <string>
using std::string;

class GradeBook
{
    public:
    GradeBook( string );
    void setCourseName( string );
    string getCourseName();
    void displayMessage();

    private:
    string courseName;
};

gradebook.cpp

#include <iostream>
using std::cout;
using std::endl;

#include "GradeBook.h"

GradeBook::GradeBook( string name )
{
    setCourseName( name );
}

void GradeBook::setCourseName( string name )
{
    if ( name.length() <= 25 )
    courseName = name;

    if ( name.length() > 25 )
    {

                courseName = name.substr( 0, 25 );

        cout << "Name "" << name << "" exceeds maximum lenght (25).n" << "Limiting courseName to first 25 characters.n" << endl;

            }

}

string GradeBook::getCourseName()
{
    return courseName;
}

void GradeBook::displayMessage()
{

        cout << "Welcome to the GradeBook forn" << getCourseName() << "!" << endl;
}

Main.cpp

#include <iostream>
using std::cout;
using std::endl;

#include "GradeBook.h"
int main()
{
    //creazione di due oggetti GradeBook
    GradeBook gradeBook1( "CS101 Introduction to C++ Programming" );
    GradeBook gradeBook2( "CS102 Data Structures in C++" );

       cout << "gradeBook1's initial name is: " << gradeBook1.getCourseName() << "ngradeBook2's initial name is: " << gradeBook2.getCourseName() << endl;

        gradeBook1.setCourseName( "CS101 C++ Programming" );

       cout << "ngradeBook1's course name is: " << gradeBook1.getCourseName() << "ngradeBook2's course name is: " << gradeBook2.getCourseName() << endl;
    return 0;
}

In my «Linker Settings» I’ve included both gradebook.h and gradebook.cpp files but that doesn’t help

Thank you,
otreblA

« Last Edit: June 23, 2010, 11:40:07 am by otreblA_SNAKE_[ITA] »


Logged

07-04-2013


#1

amber18 is offline


Registered User



07-05-2013


#8

stahta01 is offline


Registered User


Quote Originally Posted by Elysia
View Post

One project = one program.
One program consists of many source files that are merged together into one file (executable). A project is a way to keep all these files together and merge them into a single file.
So, to create a new program, create a new project. That’s all.

Technically you could just create a separate CB target for each main function.

Tim S.

«…a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match..» Bill Bryson


Перейти к контенту

otreblA_SNAKE_[ITA]

Hi there guys,
I’m studying C++ with Deitel «C++ How To Program» and I’ve done a small «gradebook» program. However I’ve a problem: when I try tu build&run my program I’ve an error:

C:UsersAlbertoAppDataLocalTempccSdybij.o:main.cpp|| multiple definition of `main’|
objDebugmain.o:C:UsersAlbertoDocumentsProgetti C++ CodeBlocksConsoleApplication24main.cpp|10|first defined here|
||=== Build finished: 2 errors, 0 warnings ===|

Here’s my simple program:

gradebook.h

#include <string>
using std::string;

class GradeBook
{
    public:
    GradeBook( string );
    void setCourseName( string );
    string getCourseName();
    void displayMessage();

    private:
    string courseName;
};

gradebook.cpp

#include <iostream>
using std::cout;
using std::endl;

#include "GradeBook.h"

GradeBook::GradeBook( string name )
{
    setCourseName( name );
}

void GradeBook::setCourseName( string name )
{
    if ( name.length() <= 25 )
    courseName = name;

    if ( name.length() > 25 )
    {

                courseName = name.substr( 0, 25 );

        cout << "Name "" << name << "" exceeds maximum lenght (25).n" << "Limiting courseName to first 25 characters.n" << endl;

            }

}

string GradeBook::getCourseName()
{
    return courseName;
}

void GradeBook::displayMessage()
{

        cout << "Welcome to the GradeBook forn" << getCourseName() << "!" << endl;
}

Main.cpp

#include <iostream>
using std::cout;
using std::endl;

#include "GradeBook.h"
int main()
{
    //creazione di due oggetti GradeBook
    GradeBook gradeBook1( "CS101 Introduction to C++ Programming" );
    GradeBook gradeBook2( "CS102 Data Structures in C++" );

       cout << "gradeBook1's initial name is: " << gradeBook1.getCourseName() << "ngradeBook2's initial name is: " << gradeBook2.getCourseName() << endl;

        gradeBook1.setCourseName( "CS101 C++ Programming" );

       cout << "ngradeBook1's course name is: " << gradeBook1.getCourseName() << "ngradeBook2's course name is: " << gradeBook2.getCourseName() << endl;
    return 0;
}

In my «Linker Settings» I’ve included both gradebook.h and gradebook.cpp files but that doesn’t help

Thank you,
otreblA

« Last Edit: June 23, 2010, 11:40:07 am by otreblA_SNAKE_[ITA] »


Logged

Я часами застреваю над проблемой, которая, вероятно, очень тривиальна.

Это самое основное использование классов.

Заголовочный файл: person.h

class person
{
protected:
std::string _Name;
public:
void setName(std::string);
};

Реализация: person.cpp

#include <string>
#include "person.h"
void person::setName(std::string name)
{
_Name = name;
}

Драйвер: main.cpp

#include <iostream>
#include "person.cpp"
int main()
{
std::cout << "Yes, it worked.n";
return 0;
}

При попытке скомпилировать этот код в CodeBlocks (используя GNU GCC), я получаю сообщение об ошибке:

~person.cpp|5|multiple definition of `person::setName(std::string)'|
~person.cpp|5|first defined here|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|

У меня есть прототип в заголовочном файле и тело в файле реализации. Где множественное определение? Это работает, если я добавлю «inline» перед «void» в person.cpp, но зачем мне в этом случае?

Кроме того, при компиляции того же точного кода в cmd, что и «g ++ main.cpp -o main.exe», он работает отлично (без встроенного)!

2

Решение

Вам не нужно включать *.cpp файл в main.cpp. Вы должны включить *.h файл.

Короче — *.cpp Файлы содержат реализацию и скомпилированы компилятором. *.h файлы содержат определения и могут быть включены из *.cpp файлы. Когда вы включаете *.cpp файл, вы получите несколько определений одного и того же объекта.

Кроме того, вам нужно добавить включить охрану

#ifndef MY_HEADER
#define MY_HEADER
... code of your header file ...
#endif

или просто добавь

#pragma once

если ваш компилятор поддерживает это.

4

Другие решения

произошло ли это сегодня.

при добавлении файла в кодовые блоки с помощью file — new и т. д. появляется экран, который спрашивает, хотите ли вы включить файл в отладочную и выпускную версии. Вы невинно отвечаете «да», ставя галочки. в результате файл автоматически включается, и когда вы явно включаете его самостоятельно, вы в конечном итоге дублируете. поэтому не ставьте галочки в этих клетках.

ура
толстяк-коротышка

2

Вы можете включить файл .cpp в другой .cpp в кодовых блоках. Но не добавляйте его в проект, который вы создали. Если файл включен в проект, блоки кода будут пытаться скомпилировать его следующим образом:

g ++ main.cpp -o main.o

g ++ person.cpp -o person.o

и затем создайте окончательный выходной файл, используя два .o файла. Поскольку main.cpp включает в себя func.cpp, вы столкнетесь с ошибкой множественного объявления.

Теперь, если вы оставите в проекте только файл main.cpp, только он будет скомпилирован, и вы не получите ту же ошибку.

0

Антон (LogRus)

Глобальный модератор

ru
Offline Offline
Пол: Мужской

Внимание! Люблю сахар в кубиках!

WWW


P.S. Разве так сложно написать (компилятору), что он не знает какой main запустить, потому что их больше одного в проекте… Криворукие программисты  Я зол!

а это что написано?

  multiple definition of `main’ ,   first defined here

научись читать. умник нашелся.
можешь спросить, а где номер строчки? и я тебе отвечу, линкер не обязан быть в курсе каким образом были получены объектные файлы, точнее компиляция какой комбинации исходных кодов привела к появлению этих файлов, за это отвечает компилятор.

Вот натолкнулся на проблему: знаю путь к папке, но как проверить, что это именно папка, а не файл?

если линукс, то используем stat
во кусок из BOOST

      status_api( const std::string & ph, error_code & ec )
      {
        struct stat path_stat;
        if ( ::stat( ph.c_str(), &path_stat ) != 0 )
        {
          if ( errno == ENOENT || errno == ENOTDIR )
          {
            ec = ok;
            return fs::file_status( fs::file_not_found );
          }
          ec = error_code( errno, system_category );
          return fs::file_status( fs::status_unknown );
        }
        ec = ok;
        if ( S_ISDIR( path_stat.st_mode ) )
          return fs::file_status( fs::directory_file );
        if ( S_ISREG( path_stat.st_mode ) )
          return fs::file_status( fs::regular_file );
        if ( S_ISBLK( path_stat.st_mode ) )
          return fs::file_status( fs::block_file );
        if ( S_ISCHR( path_stat.st_mode ) )
          return fs::file_status( fs::character_file );
        if ( S_ISFIFO( path_stat.st_mode ) )
          return fs::file_status( fs::fifo_file );
        if ( S_ISSOCK( path_stat.st_mode ) )
          return fs::file_status( fs::socket_file );
        return fs::file_status( fs::type_unknown );
      }

есть такой кусок для винды, но принцип тот же:

  template< class String >
  fs::file_status status_template( const String & ph, error_code & ec )
  {
    DWORD attr( get_file_attributes( ph.c_str() ) );
    if ( attr == 0xFFFFFFFF )
    {
      ec = error_code( ::GetLastError(), system_category );
      if ((ec.value() == ERROR_FILE_NOT_FOUND)
        || (ec.value() == ERROR_PATH_NOT_FOUND)
        || (ec.value() == ERROR_INVALID_NAME) // «tools/jam/src/:sys:stat.h», «//foo»
        || (ec.value() == ERROR_INVALID_PARAMETER) // «:sys:stat.h»
        || (ec.value() == ERROR_BAD_PATHNAME) // «//nosuch» on Win64
        || (ec.value() == ERROR_BAD_NETPATH)) // «//nosuch» on Win32
      {
        ec = ok; // these are not considered errors;
                           // the status is considered not found
        return fs::file_status( fs::file_not_found );
      }
      else if ((ec.value() == ERROR_SHARING_VIOLATION))
      {
        ec = ok; // these are not considered errors;
                           // the file exists but the type is not known
        return fs::file_status( fs::type_unknown );
      }
      return fs::file_status( fs::status_unknown );
    }
    ec = ok;;
    return (attr & FILE_ATTRIBUTE_DIRECTORY)
      ? fs::file_status( fs::directory_file )
      : fs::file_status( fs::regular_file );
  }

Undisputed, ну тогда как разорвать связь красиво?
Допустим я следующим образом видоизменю код:

general.h

C++
1
2
3
4
5
6
7
#ifndef PR1_GENERAL_H
#define PR1_GENERAL_H
 
#include "cl.h"
int sum(cl ob);
 
#endif //PR1_GENERAL_H

general.cpp

C++
1
2
3
4
5
6
#include "general.h"
 
int sum(cl ob)
{
    return ob.x + ob.y;
}

cl.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef PR1_CL_H
#define PR1_CL_H
 
#include "general.h"
 
class cl {
    int x, y;
public:
    cl() {x = 1; y = 1;}
    friend int sum(cl ob);
};
 
#endif //PR1_CL_H

Тогда в выводе я получаю:

Кликните здесь для просмотра всего текста

====================[ Build | pr1 | Debug ]=====================================
«C:Program FilesJetBrainsCLion 2019.3.3bincmakewinbincmake.exe» —build K:devcpppr1cmake-build-debug —target pr1 — -j 2
Scanning dependencies of target pr1
[ 28%] Building CXX object CMakeFiles/pr1.dir/main.cpp.obj
[ 28%] Building CXX object CMakeFiles/pr1.dir/general.cpp.obj
In file included from K:devcpppr1cl.h:9,
from K:devcpppr1main.cpp:6:
K:devcpppr1general.h:12:9: error: ‘cl’ was not declared in this scope
int sum(cl ob);
^~
In file included from K:devcpppr1main.cpp:6:
K:devcpppr1cl.h:15:25: error: ‘int sum(cl)’ redeclared as different kind of symbol
friend int sum(cl ob);
^
In file included from K:devcpppr1cl.h:9,
from K:devcpppr1main.cpp:6:
K:devcpppr1general.h:12:5: note: previous declaration ‘int sum’
int sum(cl ob);
^~~
mingw32-make.exe[3]: *** [CMakeFilespr1.dirbuild.make:62: CMakeFiles/pr1.dir/main.cpp.obj] Error 1
mingw32-make.exe[3]: *** Waiting for unfinished jobs….
mingw32-make.exe[2]: *** [CMakeFilesMakefile2:75: CMakeFiles/pr1.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFilesMakefile2:82: CMakeFiles/pr1.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: pr1] Error 2

Не понятно почему «error: ‘cl’ was not declared in this scope» ведь я же указал include’ом заголовочный файл cl.h. Судя по документации Еще на этапе препроцессинга этот кусок с определением класса должен попасть в general.h и значит определение в месте с ним.

Но если я сделаю в файле
general.h

C++
1
2
3
4
5
6
7
#ifndef PR1_GENERAL_H
#define PR1_GENERAL_H
 
class cl;
int sum(cl ob);
 
#endif //PR1_GENERAL_H

и в файле:

general.cpp

C++
1
2
3
4
5
6
7
#include "general.h"
#include "cl.h"
 
int sum(cl ob)
{
    return ob.x + ob.y;
}

, то все работает.

В общем:
1) при компиляции файла general.cpp нужно уже не просто ссылку на имя класса cl, а его определение.
2) при подключении объявлении имен в general.h достаточно знать только лишь ссылки на используемые имена ( определения не обязательно знать )

Но остается недопонимание того, почему при включении в general.h заголовочного файла cl.h происходить ругань:

K:devcpppr1general.h:9:9: error: ‘cl’ was not declared in this scope

Это что выходит, что определение не является объявлением? Мы же туда подставили целое определение…
(см. вложение)

Антон (LogRus)

Глобальный модератор

ru
Offline Offline
Пол: Мужской

Внимание! Люблю сахар в кубиках!

WWW


P.S. Разве так сложно написать (компилятору), что он не знает какой main запустить, потому что их больше одного в проекте… Криворукие программисты  Я зол!

а это что написано?

  multiple definition of `main’ ,   first defined here

научись читать. умник нашелся.
можешь спросить, а где номер строчки? и я тебе отвечу, линкер не обязан быть в курсе каким образом были получены объектные файлы, точнее компиляция какой комбинации исходных кодов привела к появлению этих файлов, за это отвечает компилятор.

Вот натолкнулся на проблему: знаю путь к папке, но как проверить, что это именно папка, а не файл?

если линукс, то используем stat
во кусок из BOOST

      status_api( const std::string & ph, error_code & ec )
      {
        struct stat path_stat;
        if ( ::stat( ph.c_str(), &path_stat ) != 0 )
        {
          if ( errno == ENOENT || errno == ENOTDIR )
          {
            ec = ok;
            return fs::file_status( fs::file_not_found );
          }
          ec = error_code( errno, system_category );
          return fs::file_status( fs::status_unknown );
        }
        ec = ok;
        if ( S_ISDIR( path_stat.st_mode ) )
          return fs::file_status( fs::directory_file );
        if ( S_ISREG( path_stat.st_mode ) )
          return fs::file_status( fs::regular_file );
        if ( S_ISBLK( path_stat.st_mode ) )
          return fs::file_status( fs::block_file );
        if ( S_ISCHR( path_stat.st_mode ) )
          return fs::file_status( fs::character_file );
        if ( S_ISFIFO( path_stat.st_mode ) )
          return fs::file_status( fs::fifo_file );
        if ( S_ISSOCK( path_stat.st_mode ) )
          return fs::file_status( fs::socket_file );
        return fs::file_status( fs::type_unknown );
      }

есть такой кусок для винды, но принцип тот же:

  template< class String >
  fs::file_status status_template( const String & ph, error_code & ec )
  {
    DWORD attr( get_file_attributes( ph.c_str() ) );
    if ( attr == 0xFFFFFFFF )
    {
      ec = error_code( ::GetLastError(), system_category );
      if ((ec.value() == ERROR_FILE_NOT_FOUND)
        || (ec.value() == ERROR_PATH_NOT_FOUND)
        || (ec.value() == ERROR_INVALID_NAME) // «tools/jam/src/:sys:stat.h», «//foo»
        || (ec.value() == ERROR_INVALID_PARAMETER) // «:sys:stat.h»
        || (ec.value() == ERROR_BAD_PATHNAME) // «//nosuch» on Win64
        || (ec.value() == ERROR_BAD_NETPATH)) // «//nosuch» on Win32
      {
        ec = ok; // these are not considered errors;
                           // the status is considered not found
        return fs::file_status( fs::file_not_found );
      }
      else if ((ec.value() == ERROR_SHARING_VIOLATION))
      {
        ec = ok; // these are not considered errors;
                           // the file exists but the type is not known
        return fs::file_status( fs::type_unknown );
      }
      return fs::file_status( fs::status_unknown );
    }
    ec = ok;;
    return (attr & FILE_ATTRIBUTE_DIRECTORY)
      ? fs::file_status( fs::directory_file )
      : fs::file_status( fs::regular_file );
  }

Я часами застреваю над проблемой, которая, вероятно, очень тривиальна.

Это самое основное использование классов.

Заголовочный файл: person.h

class person
{
protected:
std::string _Name;
public:
void setName(std::string);
};

Реализация: person.cpp

#include <string>
#include "person.h"
void person::setName(std::string name)
{
_Name = name;
}

Драйвер: main.cpp

#include <iostream>
#include "person.cpp"
int main()
{
std::cout << "Yes, it worked.n";
return 0;
}

При попытке скомпилировать этот код в CodeBlocks (используя GNU GCC), я получаю сообщение об ошибке:

~person.cpp|5|multiple definition of `person::setName(std::string)'|
~person.cpp|5|first defined here|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|

У меня есть прототип в заголовочном файле и тело в файле реализации. Где множественное определение? Это работает, если я добавлю «inline» перед «void» в person.cpp, но зачем мне в этом случае?

Кроме того, при компиляции того же точного кода в cmd, что и «g ++ main.cpp -o main.exe», он работает отлично (без встроенного)!

2

Решение

Вам не нужно включать *.cpp файл в main.cpp. Вы должны включить *.h файл.

Короче — *.cpp Файлы содержат реализацию и скомпилированы компилятором. *.h файлы содержат определения и могут быть включены из *.cpp файлы. Когда вы включаете *.cpp файл, вы получите несколько определений одного и того же объекта.

Кроме того, вам нужно добавить включить охрану

#ifndef MY_HEADER
#define MY_HEADER
... code of your header file ...
#endif

или просто добавь

#pragma once

если ваш компилятор поддерживает это.

4

Другие решения

произошло ли это сегодня.

при добавлении файла в кодовые блоки с помощью file — new и т. д. появляется экран, который спрашивает, хотите ли вы включить файл в отладочную и выпускную версии. Вы невинно отвечаете «да», ставя галочки. в результате файл автоматически включается, и когда вы явно включаете его самостоятельно, вы в конечном итоге дублируете. поэтому не ставьте галочки в этих клетках.

ура
толстяк-коротышка

2

Вы можете включить файл .cpp в другой .cpp в кодовых блоках. Но не добавляйте его в проект, который вы создали. Если файл включен в проект, блоки кода будут пытаться скомпилировать его следующим образом:

g ++ main.cpp -o main.o

g ++ person.cpp -o person.o

и затем создайте окончательный выходной файл, используя два .o файла. Поскольку main.cpp включает в себя func.cpp, вы столкнетесь с ошибкой множественного объявления.

Теперь, если вы оставите в проекте только файл main.cpp, только он будет скомпилирован, и вы не получите ту же ошибку.

0

Я застрял часами по проблеме, которая, вероятно, очень тривиальна.

Это самое основное использование классов.

Заголовок файла: person.h

class person
{
  protected:
    std::string _Name;
  public:
    void setName(std::string);
};

Реализация: person.cpp

#include <string>
#include "person.h"

void person::setName(std::string name)
{
  _Name = name;
}

Драйвер: main.cpp

#include <iostream>
#include "person.cpp"

int main()
{
  std::cout << "Yes, it worked.n";
  return 0;
}

При попытке скомпилировать этот код в CodeBlocks (используя GNU GCC), я получаю сообщение об ошибке:

~person.cpp|5|multiple definition of 'person::setName(std::string)'|
~person.cpp|5|first defined here|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|

У меня есть прототип в файле заголовка и тело в файле реализации. Где множественное определение? Он работает, если я добавлю «inline» перед «void» в person.cpp, но почему я должен в этом случае?

Кроме того, при компиляции этого же точного кода в cmd как «g++ main.cpp -o main.exe», он отлично работает (без встроенного)!

You cannot have two main functions in the same project. Put them in separate projects or rename one of the functions and call it from the other main function.

You can never have more than one main() function in your project since it is the entrypoint, no matter what the parameter list is like.

You can however have multiple declarations of other functions as long as the parameter list is different (function overloading).

File 1

#include <iostream>

using namespace std;

int main()
{
    cout<<"Hello World";
    otherFunction();
    return 0;
}

File 2

#include <iostream>

using namespace std;

void otherFunction()
{
    cout<<"Demo Program";
}

Dont forget the appropiate #includes.

C++

Overview

In this post, we will fix the error multiple definition of `main’ in C++ project. The error occurs if the C++ project has multiples main functions defined in the project.

Error

Sample error log:

Documents/CProjects/TestingDocsProject/syntax.cpp:10: multiple definition of `main’
objDebugmain.o:/Documents/CProjects/TestingDocsProject/main.cpp:10: first defined here

C++ Multiple Definition of Main Error

In this example, the source code files syntax.cpp and main.cpp contains the main() routine defined.

Error Fix

The main function is the entry point for the C++ program execution.
The fix for the error is to scan the source files listed in the build log and remove the unwanted main routines in the respective files. We can have one definition of the main function for the project to run.

Alternatively, we can also remove source code files from the project which has multiple definitions of the main routine.

That’s it. This will resolve the error in the project.

Возможно, вам также будет интересно:

  • Multi tool неизвестная ошибка при определении подключенного устройства
  • Mwfix ru исправление ошибок windows 7
  • Mudrunner ошибка соединения с сервером игры
  • Mw2 ошибка соединения со steam
  • Mudrunner ошибка при запуске приложения 0xc0000142

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии