Error main file cannot be included recursively when building a preamble

When building a header-only library it is very likely that we include the implementation header at the end of the main header as well as the main header at the beginning of the implementation heade...

When building a header-only library it is very likely that we include the implementation header at the end of the main header as well as the main header at the beginning of the implementation header.

The reason is very simple, the user shall only include the main header, hence the main header is responsible for including its implementation. On the other hand, while developing the header-only library, it’s necessary to include the main header file at the beginning in order to benefit from Clangd features.

However, if this approach is used, Clangd will report an error stating we cannot include the main file recursively when building a preamble.

{
	"resource": "/home/user/Library/include/impl/feature_a.hpp",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "pp_including_mainfile_in_preamble",
	"severity": 8,
	"message": "In included file: main file cannot be included recursively when building a preamble",
	"source": "clang",
	"startLineNumber": 1,
	"startColumn": 10,
	"endLineNumber": 1,
	"endColumn": 47,
	"relatedInformation": [
		{
			"startLineNumber": 328,
			"startColumn": 10,
			"endLineNumber": 328,
			"endColumn": 52,
			"message": "Error occurred here",
			"resource": "/home/user/Library/include/feature_a.hpp"
		}
	]
}

For example:

Header definition

// include/feature_a.hpp
#ifndef MY_HEADER_ONLY_LIBRARY_FEATURE_A_HPP
#define MY_HEADER_ONLY_LIBRARY_FEATURE_A_HPP
...
// header definition
...
// include the implementation file
#include "impl/feature_a.hpp"
#endif

Header implementation

// include/impl/feature_a.hpp
// No need for header-guards
// Include the main header definition - so we can implement using clangd features.
// Note - this is not a requirement for compilation since this is being included in the header file.
#include "feature_a.hpp"
...
// header implementation
...

What I expected

Since the main header file has header-guards, clangd should check that, even though the file is being recursively included, the header-guards will stop the recursion safely.

System information
Output of clangd --version: clangd version 9.0.0-2~ubuntu18.04.2 (tags/RELEASE_900/final)
Editor/LSP plugin: VSCode with ClangD extension.
Operating system: Ubuntu 18.04

Forum Updated on Feb 6th

This topic has been deleted. Only users with topic management privileges can see it.

  • I am getting below error in qt creator.

    Error — in included file: main file cannot be included recursively when building a preamble

    Please provide solution on this error

  • @Abhijeet-Gurav said in General include file error:

    Please provide solution on this error

    Please provide more information.
    What are you including where? It looks like you have reqursive includes.

  • In 1 user defined include file I am including another user defined include file with one more user defined include file. Total 3 user defined include files.
    and in that one more user defined include file I need another user defined include file so I am including that.
    This is little bit confusing but in this case I am getting error.

  • @Abhijeet-Gurav
    Well the «solution» is to untangle your #includes so that you don’t need a circular include. You probably should not need to. Otherwise check the #ifndef guard statements at the head of each included file which Qt would put in for you if you let it create the files from classes or you may have put in yourself.

Differential D53866

Authored by nik on Oct 30 2018, 7:12 AM.

  • Edit Revision
  • Update Diff
  • Download Raw Diff
  • Mute Notifications
  • Award Token
  • Flag For Later
  • Restricted Project
arphaman
cfe-commits
jan-wassenberg
jdoerfert
yvvan
Reviewers
erikjv
ilya-biryukov
Repository
rC Clang
Build Status
Buildable 31737
Build 31736: arc lint + arc unit

Event Timeline

nik created this revision.

Herald added subscribers: cfe-commits, arphaman.

Harbormaster completed remote builds in B24325: Diff 171689.

nik added reviewers: erikjv, ilya-biryukov.

nik added a subscriber: yvvan.

Comment Actions

Comment Actions

Comment Actions

Comment Actions

Comment Actions

Comment Actions

Comment Actions

Comment Actions

Comment Actions

Harbormaster completed remote builds in B25314: Diff 175210.

Comment Actions

ilya-biryukov added inline comments.

include/clang/Lex/Preprocessor.h
391 ↗ (On Diff #175210)
lib/Lex/PPDirectives.cpp
1883

nik marked 2 inline comments as done.

nik added inline comments.

include/clang/Lex/Preprocessor.h
391 ↗ (On Diff #175210)
lib/Lex/PPDirectives.cpp
1883

Comment Actions

Harbormaster completed remote builds in B25731: Diff 176826.

nik retitled this revision from [Preamble] Fix preamble for circular #includes to [Preamble] Stop generating preamble for circular #includes.

nik edited the summary of this revision. (Show Details)

ilya-biryukov added inline comments.

include/clang/Lex/Preprocessor.h
391 ↗ (On Diff #175210)
lib/Lex/PPDirectives.cpp
1883
1884

nik marked 2 inline comments as done and an inline comment as not done.

nik added inline comments.

include/clang/Lex/Preprocessor.h
391 ↗ (On Diff #175210)

Comment Actions

Harbormaster completed remote builds in B25758: Diff 176941.

ilya-biryukov added inline comments.

include/clang/Basic/DiagnosticLexKinds.td
430
include/clang/Lex/Preprocessor.h
391 ↗ (On Diff #175210)

nik marked 2 inline comments as done.

nik added inline comments.

include/clang/Lex/Preprocessor.h
391 ↗ (On Diff #175210)

Herald added a project: Restricted Project.

Herald added a subscriber: jdoerfert.

Comment Actions

Harbormaster completed remote builds in B28137: Diff 186813.

nik marked an inline comment as done.

nik added inline comments.

lib/Basic/SourceManager.cpp
1594

nik retitled this revision from [Preamble] Stop generating preamble for circular #includes to [Preamble] Stop circular inclusion of main file when building preamble.

nik edited the summary of this revision. (Show Details)

Comment Actions

Comment Actions

Comment Actions

Comment Actions

Harbormaster completed remote builds in B31610: Diff 198654.

Comment Actions

lib/Basic/SourceManager.cpp
1594

nik marked an inline comment as done.

nik added inline comments.

lib/Basic/SourceManager.cpp
1594

Comment Actions

Harbormaster completed remote builds in B31666: Diff 198799.

ilya-biryukov added inline comments.

lib/Basic/SourceManager.cpp
1594

nik marked an inline comment as done.

nik added inline comments.

lib/Basic/SourceManager.cpp
1594

Comment Actions

include/clang/Basic/DiagnosticLexKinds.td
429
lib/Basic/SourceManager.cpp
1594

This revision is now accepted and ready to land.

Comment Actions

Harbormaster completed remote builds in B31737: Diff 198997.

Comment Actions

Comment Actions

Comment Actions

  • Files
  • History
  • Commits
Path Size

include/

clang/

Basic/

DiagnosticLexKinds.td

2 lines

lib/

Basic/

SourceManager.cpp

2 lines

Lex/

PPDirectives.cpp

12 lines

test/

Index/

preamble-cyclic-include.cpp

9 lines

View Options

Loading…

View Options

Loading…

View Options

Loading…

View Options

Loading…

Log In to Comment

For example:
I have a class called A. And there is:

A.hpp
A.cpp
main.cpp

for my project

By default, I only need to include A.hpp in the main so I can compile it, either using IDE such as Xcode or using:

g++ main.cpp A.cpp -o xxxxx

But the submission system only allows me to use:

g++ main.cpp -o xxxx

I tried to include A.cpp in the main, but the IDE says: main file cannot be included recursively when building a preamble

Is there any solution? I want to keep my hpp and cpp separately.

asked Sep 15, 2020 at 13:37

jonapple29's user avatar

12

Can I include a cpp file

In theory, any file can be included.

But as a convention, you should never include cpp files.

But the submission system only allows me to use:

g++ main.cpp -o xxxx

If you cannot compile A.cpp then don’t write such file at all. Write the definitions that you would have written in A.cpp into main.cpp instead. This achieves the same as including with a macro, but there won’t be duplicate definitions in another cpp file.

answered Sep 15, 2020 at 14:21

eerorika's user avatar

eerorikaeerorika

229k12 gold badges193 silver badges318 bronze badges

You can #include any file you want. #include is automatic copy-paste. It looks in the file you tell it to include, and it reads whatever’s in the file, and it pretends you wrote that in your original file. It doesn’t care what’s in the file, it just does that. You can include a .h file, a .hpp file, a .cpp file, a .txt file, a .py file, a .jpg file, or anything you want, as long as it’s got valid C++ code in it.

Note that including a .cpp file is not the same as compiling it separately. And people expect that .cpp files are compiled separately, not included. To avoid confusing other programmers or the future version of yourself, you should rename the file to something else if you want to include it. You don’t have to, but you should. If it’s not a normal header file either (because you can’t include it more than once), then you can make up some completely different extension, like .inc.

answered Sep 15, 2020 at 14:21

user253751's user avatar

user253751user253751

55.4k6 gold badges45 silver badges88 bronze badges

2019-11-25 12:35:13,620 - INFO - Received ready request
2019-11-25 12:35:13,623 - INFO - Received signature help available request
2019-11-25 12:35:13,624 - INFO - Received event notification
2019-11-25 12:35:13,626 - INFO - Received event notification
2019-11-25 12:35:13,626 - INFO - Adding buffer identifiers for file: /Users/maxcoplan/test.c
2019-11-25 12:35:13,635 - ERROR - No Clangd executable found at /usr/local/Cellar/llvm/9.0.0/bin/clangd
2019-11-25 12:35:13,635 - ERROR - Semantic completion not available for ['c']
Traceback (most recent call last):
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 114, in FiletypeCompletionAvailable
    self.GetFiletypeCompleter( filetypes )
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 100, in GetFiletypeCompleter
    current_filetypes ) )
ValueError: No semantic completer exists for filetypes: ['c']
2019-11-25 12:35:13,636 - ERROR - Semantic completion not available for ['c']
Traceback (most recent call last):
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 114, in FiletypeCompletionAvailable
    self.GetFiletypeCompleter( filetypes )
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 100, in GetFiletypeCompleter
    current_filetypes ) )
ValueError: No semantic completer exists for filetypes: ['c']
2019-11-25 12:35:13,725 - INFO - Received filetype completion available request
2019-11-25 12:35:13,725 - ERROR - Semantic completion not available for ['c']
Traceback (most recent call last):
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 114, in FiletypeCompletionAvailable
    self.GetFiletypeCompleter( filetypes )
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 100, in GetFiletypeCompleter
    current_filetypes ) )
ValueError: No semantic completer exists for filetypes: ['c']
2019-11-25 12:35:13,780 - INFO - Received event notification
2019-11-25 12:35:13,781 - INFO - Adding ONE buffer identifier for file: /Users/maxcoplan/test.c
2019-11-25 12:35:13,781 - ERROR - Semantic completion not available for ['c']
Traceback (most recent call last):
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 114, in FiletypeCompletionAvailable
    self.GetFiletypeCompleter( filetypes )
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 100, in GetFiletypeCompleter
    current_filetypes ) )
ValueError: No semantic completer exists for filetypes: ['c']
2019-11-25 12:35:14,387 - INFO - Received event notification
2019-11-25 12:35:14,387 - INFO - Adding buffer identifiers for file: /Users/maxcoplan/test.c
2019-11-25 12:35:14,387 - ERROR - Semantic completion not available for ['c']
Traceback (most recent call last):
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 114, in FiletypeCompletionAvailable
    self.GetFiletypeCompleter( filetypes )
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 100, in GetFiletypeCompleter
    current_filetypes ) )
ValueError: No semantic completer exists for filetypes: ['c']
2019-11-25 12:35:14,388 - INFO - Received event notification
2019-11-25 12:35:14,388 - ERROR - Semantic completion not available for ['c']
Traceback (most recent call last):
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 114, in FiletypeCompletionAvailable
    self.GetFiletypeCompleter( filetypes )
  File "/Users/maxcoplan/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_state.py", line 100, in GetFiletypeCompleter
    current_filetypes ) )
ValueError: No semantic completer exists for filetypes: ['c']
2019-11-25 12:35:18,445 - INFO - Received completion request
2019-11-25 12:35:18,445 - ERROR - Semantic completion not available for ['c']
Traceback (most recent call last):
  Fi

I have installed clangd with :LspInstallServer but the diagnostic throws errors when I include any standard library files.
#include <string> results in:

main.cpp|1 col 10| clang:Error:pp_file_not_found:In included file: 'string.h' file not found /Users/maciej/.vim/bundle/vim-lsp-settings/servers/clangd/bin/../include/c++/v1/string.h:60:15: note: error     occurred here 

I took a look at the string in the .vim/bundle/vim-lsp-settings/servers/clangd/bin/../include/c++/v1/ and it fails at:

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#include_next <string.h>

with the diagnostics:

string.h|57 col 13| clang:Warning:-Wpragma-system-header-outside-header:#pragma system_header ignored in main file
string.h|57 col 13| clang:Warning:-Wpragma-system-header-outside-header:#pragma system_header ignored in main file
string.h|60 col 15| clang:Error:pp_including_mainfile_in_preamble:Main file cannot be included recursively when building a preamble

I am not sure whether it is my fault, something wrong with the vim-lip-settings or with the llvm code that is downloaded with the :LspInstallServer, but the c++ diagnostics doesn’t work out of the box.

Also it results in very superficial autocompletion of stl, because the clangd can’t parse the library and does not complete methods/members of classes.

Recommend Projects

  • React photo

    React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo

    Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo

    Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo

    TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo

    Django

    The Web framework for perfectionists with deadlines.

  • Laravel photo

    Laravel

    A PHP framework for web artisans

  • D3 photo

    D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Visualization

    Some thing interesting about visualization, use data art

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo

    Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo

    Microsoft

    Open source projects and samples from Microsoft.

  • Google photo

    Google

    Google ❤️ Open Source for everyone.

  • Alibaba photo

    Alibaba

    Alibaba Open Source for everyone

  • D3 photo

    D3

    Data-Driven Documents codes.

  • Tencent photo

    Tencent

    China tencent open source team.

12 / 12 / 0

Регистрация: 31.08.2011

Сообщений: 458

1

14.07.2014, 06:31. Показов 5707. Ответов 11


Ошибка выскакивает в файле fig11_08.cpp на 8 строке. Уже второй раз сталкиваюсь с этим и понял, что так дело больше не пойдет, надо разобраться. Помогите понять, что он хочет.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



12 / 12 / 0

Регистрация: 31.08.2011

Сообщений: 458

14.07.2014, 07:22

 [ТС]

2

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



0



uglyPinokkio

327 / 230 / 55

Регистрация: 30.05.2014

Сообщений: 682

14.07.2014, 08:08

3

Цитата
Сообщение от Тимур05
Посмотреть сообщение

в файлах кое где остались синтакс ошибки. Это может быть причиной?

Может

Добавлено через 37 минут
Синтаксис поправил, логику не смотрел

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Рис. 11.6: Array.h 
// Класс массива для хранения целых чисел. 
#ifndef ARRAY_H 
#define ARRAY_H 
 
#include <iostream> 
 
using std::ostream; 
using std::istream; 
 
class Array
{ 
   friend ostream& operator<<( ostream &, const Array & ); 
   friend istream& operator>>( istream &, Array & ); 
   public: 
   Array( int = 10 ); // конструктор по умолчанию 
   Array( const Array & ); // конструктор копии 
   ~Array(); // деструктор 
   int getSize() const; // возвратить размер 
   
   const Array &operator=( const Array & ); // операция присваивания 
   bool operator==( const Array & ) const; // операция равенства 
   
   // операция неравенства; результат противоположен операции == 
   bool operator!=( const Array right ) const 
   { 
     return ! ( *this == right ); // вызывает Array::operator== 
   } // конец функции operator!= 
   
   // индексация для неконстантных объектов возвращает lvalue 
   int &operator[]( int ); 
   
   // индексация для константных объектов возвращает rvalue 
   int operator[]( int ) const; 
   private: 
   int size; // размер массива, заданного указателем 
   int *ptr; // указатель на первый элемент массива 
}; // конец класса Array 
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Рис 11.7: Array.срр 
// Определения элемент-функций для класса Array 
#include <iostream> 
using std::cerr; 
using std::cout; 
using std::cin; 
using std::endl; 
 
#include <iomanip> 
using std::setw; 
 
#include <cstdlib> // прототип функции exit 
using std::exit; 
 
#include "Array.h" // определение класса Array 
 
// конструктор Array по умолчанию (размер по умолчанию 10) 
Array::Array( int arraySize ) 
{ 
   size = ( arraySize > 0 ? arraySize : 10 ) ; // проверить arraySize 
   ptr = new int[ size ]; // выделить пространство для массива 
   
   for ( int i = 0; i < size; i++ ) 
       ptr[ i ] =0; // установить элемент массива-указателя 
} // конец конструктора Array по умолчанию 
 
// конструктор копии для класса Array; 
// для предотвращения бесконечной рекурсии должен возвращать ссылку 
Array::Array( const Array &arrayToCopy ) 
: size( arrayToCopy.size ) 
{ 
   ptr = new int[ size ] ; // выделить пространство для массива 
   
   for ( int i = 0; i < size; i++ ) 
       ptr[ i ] = arrayToCopy.ptr[ i ]; // копировать в объект 
} // конец конструктора копии Array 
 
// деструктор для класса Array 
Array::~Array() 
{ 
  delete [] ptr; // освободить пространство массива 
} // конец деструктора 
 
// возвратить число элементов Array 
int Array::getSize() const 
{ 
  return size; // число элементов в Array 
} // конец функции getSize 
 
// перегруженная операция присваивания; 
// возвращаемая константа предотвращает: ( al = а2 ) = аЗ 
const Array & Array::operator=( const Array &right ) 
{ 
   if ( &right != this ) // избегать самоприсваивания 
   { 
      // для массивов разного размера освободить исходный массив 
      //в левой части, затем выделить новый массив для левой части 
      if ( size != right.size ) 
      { 
         delete [] ptr; // освободить пространство 
         size = right.size; // переустановить размер этого объекта 
         ptr = new int[ size ]; // создать пространство для копии 
      } // конец внутреннего if 
      
      for ( int i = 0; i < size; i++ ) 
      ptr[ i ] = right.ptr[ i ]; // копировать массив в объект 
   } // конец внешнего if 
   
   return *this; // позволяет писать, например, х = у = z 
} // конец функции operator= 
 
// определить, равны ли два массива, если равны, 
// возвратить true, в противном случае возвратить false 
bool Array::operator==( const Array &right ) const 
{ 
   if ( size != right.size ) 
   return false; // массивы с различным числом элементов 
   
   for ( int i = 0; i < size; i++ ) 
      if ( ptr[ i ] != right.ptr[ i ] ) 
         return false; // содержимое массивов различно 
   
   return true; // массивы равны 
} // конец функции operator= 
 
// перегруженная операция индексации для неконстантных массивов; 
// возврат ссылки создает модифицируемое lvalue 
int &Array::operator[]( int subscript ) 
{ 
   // проверить индекс на выход за пределы массива 
   if ( subscript < 0 || subscript >= size ) 
   { 
      cerr << "nError: Subscript " << subscript 
      << " out of range" << endl; 
      exit( 1 ); // завершить программу; индекс вне диапазона 
   } // конец if 
   
   return ptr[ subscript ]; // возврат ссылки 
} // конец функции operator[] 
 
// перегруженная операция индексации для константных массивов; 
// возврат константной ссылки создает rvalue 
int Array::operator[]( int subscript ) const 
{ 
   // проверить индекс на выход за пределы массива 
   if ( subscript < 0 || subscript >= size ) 
   { 
      cerr << "nError: Subscript " << subscript 
      << " out of range" << endl; 
      exit( 1 ); // завершить программу; индекс вне диапазона 
   } // конец if 
   
   return ptr[ subscript ]; // возвращает копию элемента 
} // конец функции operator[] 
 
// перегруженная операция ввода для класса Array; 
// вводит значения для всего массива 
istream &operator>>( istream &input, Array &a ) 
{ 
   for ( int i = 0; i < a.size; i++ ) 
       input >> a.ptr[ i ]; 
   
   return input; // enables cin >> x >> y; 
} // конец функции operator>> 
 
// перегруженная операция вывода для класса Array 
ostream &operator<<( ostream &output, const Array &a ) 
{ 
   int i; 
   
   // вывести закрытый массив, адресуемый указателем 
   for ( i = 0; i < a.size; i++ ) 
   { 
      output << setw( 12 ) << a.ptr[ i ]; 
      
      if ( ( i + 1 ) % 4 == 0 ) // no 4 числа в строке вывода 
         output << endl; 
   } // конец for 
   
   if ( i % 4 != 0 ) // закончить последнюю строку вывода 
      output << endl; 
   
   return output; // позволяет писать cout << x << y; 
} // конец функции operator<<
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Рис. 11.8: fig11_08.cpp 
// Тестовая программа для класса Array. 
#include <iostream> 
using std::cout; 
using std::cin; 
using std::endl; 
 
#include "Array.h" 
 
int main() 
{ 
   Array integers1( 7 ); // 7-элементный Array 
   Array integers2; // 10-элементный Array по умолчанию 
   
   // напечатать размер и содержимое integers1 
   cout << "Size of Array integersl is " 
   << integers1.getSize() 
   << "nArray after initialization:n" << integers1; 
   
   // напечатать размер и содержимое integers2 
   cout << "nSize of Array integers2 is " 
   << integers2.getSize() 
   << "nArray after initialization:n" << integers2; 
   
   // ввести и напечатать integersl и integers2 
   cout << "nEnter 17 integers:" << endl; 
   cin >> integers1 >> integers2; 
   
   cout << "nAfter input, the Arrays contain:n" 
   << "integers1:n" << integers1 
   << "integers2:n" << integers2; 
   
   // применить перегруженную операцию неравенства (!=) 
   cout << "nEvaluating: integersl != integers2" << endl; 
   
   if ( integers1 != integers2 ) 
      cout << "integersl and integers2 are not equal" << endl; 
   
   // создать массив integers3, используя как инициализатор 
   // integersl; напечатать размер и содержимое 
   Array integers3( integers1 ); // вызывает конструктор копии 
   
   cout << "nSize of Array integers3 is " 
   << integers3.getSize() 
   << "nArray after initialization:n" << integers3; 
   
   // применить перегруженную операцию присваивания (=) 
   cout << "nAssigning integers2 to integersl:" << endl; 
   integers1 = integers2; // заметьте, что целевой массив меньше 
   
   cout << "integersl:n" << integers1 
   << "integers2:n" << integers2; 
   
   // применить перегруженную операцию равенства (==) 
   cout << "nEvaluating: integers1 == integers2" << endl; 
   
   if ( integers1 == integers2 ) 
      cout << "integersl and integers2 are equal" << endl; 
   
   // применить перегруженную операцию индексации, дающую rvalue 
   cout << "nintegers1[5] is " << integers1[ 5 ]; 
   
   // применить перегруженную операцию индексации, дающую lvalue 
   cout << "nnAssigning 1000 to integers1[5]" << endl; 
   integers1[ 5 ] = 1000; 
   cout << "integersl:n" << integers1; 
   
   // попытка использования индекса вне диапазона 
   cout << "nAttempt to assign 1000 to integersl[15]" << endl; 
   integers1[ 15 ] = 1000; // ОШИБКА: выход за диапазон 
   return 0; 
} // конец main



1



12 / 12 / 0

Регистрация: 31.08.2011

Сообщений: 458

17.07.2014, 23:46

 [ТС]

4

ты крут, мега мозг ). Я то сверяю каждую строчку с книгой и то пропустил где-то, а ты просто сверял со своей логикой и получилось.

Добавлено через 40 минут

Цитата
Сообщение от uglyPinokkio
Посмотреть сообщение

Синтаксис поправил

Как ты это сделал, открой секрет. Сейчас другой проект скопировал, опять та же ошибка. Не поленился прошел каждую строчку отдельно, сверил, все равно ошибка выскакивает. Может какая метода есть у тебя?



0



327 / 230 / 55

Регистрация: 30.05.2014

Сообщений: 682

18.07.2014, 06:10

5

Цитата
Сообщение от Тимур05
Посмотреть сообщение

Может какая метода есть у тебя?

Нет, просто я этим на жизнь зарабатываю .



0



Тимур05

12 / 12 / 0

Регистрация: 31.08.2011

Сообщений: 458

18.07.2014, 14:04

 [ТС]

6

Есть еще один не большой проект, хочу показать тебе, может поможешь, просто указать где ошибки, чтоб самому понять, что я пропустил. Здесь я сам каждую строчку проверил по книге, строка в строку, но все равно выскакивает ошибка (название темы). В комментариях если есть ошибки, то их я игнорирую, так как компилятор то же не смотрит на них.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Ðèñ. 11.9: String.h 
// Îïðåäåëåíèå êëàññà String. 
#ifndef STRING_H 
#define STRING_H 
 
#include <iostream> 
using std::ostream; 
using std::istream; 
 
class String 
{ 
   friend îstream &operator<<( ostream &, const String & ) ; 
   friend istream &operator>>( istream &, String & ) ; 
public: 
   String( const char * = "" ); // ê-òîð ïðåîáðàçîâàíèÿ/ïî óìîë÷àíèþ 
   String( const String & ); // êîíñòðóêòîð êîïèè 
   ~String(); // äåñòðóêòîð 
   
   const String &operator=( const String & ); // on. ïðèñâàèâàíèÿ 
   const String &operator+=( const String & ); // on. êîíêàòåíàöèè 
   
   bool operator!() const; // ïóñòà ëè ñòðîêà? 
   bool operator==( const String & ) const; // ïðîâåðèòü si == s2 
   bool operator<( const String & ) const; // ïðîâåðèòü si < s2 
   
   // ïðîâåðèòü si != s2 
   bool operator!=( const String &right ) const 
   { 
     return !( *this == right ); 
   } // êîíåö ôóíêöèè operator!= 
   
   // ïðîâåðèòü si > s2 
   bool operator>( const String &right ) const 
   { 
     return right < *this; 
   } // êîíåö ôóíêöèè operator> 
   
   // ïðîâåðèòü si <= s2 
   bool operator<=( const String &right ) const 
   { 
     return !( right < *this ); 
   } // êîíåö ôóíêöèè operator <= 
   
   // ïðîâåðèòü si >= s2 
   bool operator>=( const String &right ) const 
   { 
     return !( *this < right ); 
   } // êîíåö ôóíêöèè operator>= 
   
   char &operator[]( int ); // îïåðàöèÿ èíäåêñàöèè (lvalue) 
   char operator[]( int ) const; // îïåðàöèÿ èíäåêñàöèè (rvalue) 
   String operator()( int, int = 0 ) const; // âîçâðàòèòü ïîäñòðîêó 
   int getLength() const; // âîçâðàòèòü äëèíó ñòðîêè 
private: 
   int length; // äëèíà ñòðîêè (íå ñ÷èòàÿ çàâåðøàþùèé íóëü) 
   char *sPtr; // óêàçàòåëü íà íà÷àëî ïðåäñòàâëåíèÿ ñòðîêè
   
   void setString( const char * ); // âñïîìîãàòåëüíàÿ ôóíêöèÿ 
}; // êîíåö êëàññà String 
 
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Ðèñ. 11.10: String.ñðð 
// Îïðåäåëåíèå ýëåìåíò-ôóíêöèé äëÿ êëàññà String. 
#include <iostream> 
using std::cerr; 
using std::cout; 
using std::endl; 
 
#include <iomanip> 
using std::setw; 
 
#include <cstring> // ïðîòîòèïû strcpy è streat 
using std::strcmp; 
using std::strcpy; 
using std::strcat; 
 
#include <cstdlib> // ïðîòîòèï exit 
using std::exit; 
 
#include "String.h" // îïðåäåëåíèå êëàññà String 
 
// êîíñòðóêòîð ïðåîáðàçîâàíèÿ (è ïî óìîë÷àíèþ) char* â String 
String::String( const char *s ) 
: length( ( s != 0 ) ? strlen( s ) : 0 ) 
{ 
   cout << "Conversion (and default) constructor: " << s << endl; 
   setString( s ); // call utility function 
} // êîíåö êîíñòðóêòîðà ïðåîáðàçîâàíèÿ String 
 
// êîíñòðóêòîð êîïèè 
String::String( const String &copy ) 
: length( copy.length ) 
{ 
   cout << "Copy constructor: " << copy.sPtr << endl; 
   setString( copy.sPtr ); // call utility function 
} // êîíåö êîíñòðóêòîðà êîïèè String 
 
// äåñòðóêòîð 
String::~String() 
{ 
   cout << "Destructor: " << sPtr << endl; 
   delete [] sPtr; // îñâîáîäèòü ñòðîêó, ïðåäñòàâëåííóþ óêàçàòåëåì 
} // êîíåö äåñòðóêòîðà -String 
 
// ïåðåãðóæåííàÿ îïåðàöèÿ =; ïðåäîòâðàùàåò ñàìîïðèñâàèâàíèå 
const String &String::operator=( const String &right ) 
{ 
   cout << "operator= called" << endl; 
   
   if ( &right != this ) // ïðåäîòâðàòèòü ñàìîïðèñâàèâàíèå 
   { 
      delete [] sPtr; // ïðåäîòâðàùàåò óòå÷êó ïàìÿòè 
      length = right.length; // íîâàÿ äëèíà ñòðîêè 
      setString( right.sPtr ); // âûçâàòü âñïîìîãàòåëüíóþ ôóíêöèþ 
   } // êîíåö if 
   else 
        cout << "Attempted assignment of a String to itself" << endl; 
   
   return *this; // ðàçðåøàåò êàñêàäíîå ïðèñâàèâàíèå 
} // êîíåö ôóíêöèè operator= 
 
// ïðèñîåäèíèòü ïðàâûé îïåðàíä ê îáúåêòó è ñîõðàíèòü â îáúåêòå 
const String &String::operator+=( const String &right ) 
{ 
   size_t newLength = length + right.length; // íîâàÿ äëèíà 
   char *tempPtr = new char[ newLength + 1 ]; // âûäåëèòü ïàìÿòü 
   
   strcpy( tempPtr, sPtr ); // êîïèðîâàòü sPtr 
   strcpy( tempPtr + length, right.sPtr ); // êîïèðîâàòü right.sPtr 
   
   delete [] sPtr; // îñâîáîäèòü ñòàðûé ìàññèâ 
   sPtr = tempPtr; // ïðèñâîèòü sPtr íîâûé ìàññèâ 
   length = newLength; // ïðèñâîèòü length íîâóþ äëèíó 
   return *this; // ðàçðåøàåò êàñêàäíûå âûçîâû 
} // êîíåö ôóíêöèè operator+= 
 
// Ïóñòà ëè ñòðîêà? 
bool String::operator!() const 
{ 
  return length == 0; 
} // êîíåö ôóíêöèè operator! 
 
// Ðàâíà ëè äàííàÿ ñòðîêà ïðàâîé ñòðîêå? 
bool String::operator==( const String &right ) const 
{ 
  return strcmp( sPtr, right.sPtr ) == 0; 
} // êîíåö ôóíêöèè operator== 
 
// Ìåíüøå ëè äàííàÿ ñòðîêà ïðàâîé ñòðîêå? 
bool String::operator<( const String &right ) const 
{ 
  return strcmp( sPtr, right.sPtr ) < 0; 
} // êîíåö ôóíêöèè operator< 
 
// âîçâðàòèòü ññûëêó íà ñèìâîë ñòðîêè êàê ìîäèôèöèðóåìîå lvalue 
char &String::operator[] ( int subscript ) 
{ 
   // ïðîâåðèòü íà âûõîä èíäåêñà èç äèàïàçîíà 
   if ( subscript < 0 || subscript >= length ) 
   { 
      cerr << "Error: Subscript " << subscript 
      << " out of range" << endl; 
      exit( 1 ); // çàâåðøèòü ïðîãðàììó 
   } // êîíåö if 
   
   return sPtr[ subscript ]; // ìîäèôèöèðóåìîå lvalue 
} // êîíåö ôóíêöèè operator[] 
 
// âîçâðàòèòü ññûëêó íà ñèìâîë ñòðîêè êàê rvalue 
char String::operator[] ( int subscript ) const 
{ 
   // ïðîâåðèòü íà âûõîä èíäåêñà èç äèàïàçîíà 
   if ( subscript < 0 || subscript >= length ) 
   { 
      cerr << "Error: Subscript " << subscript 
      << " out of range" << endl; 
      exit( 1 ); // çàâåðøèòü ïðîãðàììó 
   } // êîíåö if 
   
   return sPtr[ subscript ]; // âîçâðàùàåò êîïèþ ýëåìåíòà 
} // êîíåö ôóíêöèè operator[] 
 
// âîçâðàòèòü ïîäñòðîêó, íà÷èíàþùóþñÿ ñ index è äëèíîé subLength 
String String::operator()( int index, int subLength ) const 
{ 
   // åñëè èíäåêñ âíå äèàïàçîíà èëè äëèíà ñòðîêè < 0, 
   // âîçâðàòèòü ïóñòîöé îáúåêò String 
   if ( index < 0 || index >= length || subLength < 0 ) 
      return ""; // àâòîìàòè÷åñêè ïðåîáðàçóåòñÿ â îáúåêò String 
   
   // îïðåäåëèòü äëèíó ïîäñòðîêè 
   int len; 
   
   if ( ( subLength == 0 ) || ( index + subLength > length ) ) 
      len = length - index; 
   else 
        len = subLength; 
   
   // âûäåëèòü âðåìåííûé ìàññèâ äëÿ ïîäñòðîêè 
   //è çàâåðøàþùåãî íóëåâîãî ñèìâîëà 
   char *tempPtr = new char[ len + 1 ]; 
   
   // êîïèðîâàòü ñòðîêó â ìàññèâ è çàâåðøèòü ñòðîêó 
   strncpy( tempPtr, &sPtr[ index ], len ); 
   tempPtr[ len ] = ''; 
   
   // ñîçäàòü âðåìåííûé îáúåêò String, ñîäåðæàùèé ïîäñòðîêó 
   String tempString( tempPtr ); 
   delete [] tempPtr; // óäàëèòü âðåìåííûé ìàññèâ 
   return tempString; // âîçâðàòèòü êîïèþ âðåìåííîãî îáúåêòà String 
} // êîíåö ôóíêöèè operator() 
 
// âîçâðàòèòü äëèíó ñòðîêè 
int String::getLength() const 
{ 
  return length; 
} // êîíåö ôóíêöèè getLength 
 
// âñïîìîãàòåëüíàÿ ôóíêöèÿ, âûçûâàåìàÿ êîíñòðóêòîðàìè è operator= 
void String::setstring( const char *string2 ) 
{ 
   sPtr = new char[ length +1 ]; // âûäåëèòü ïàìÿòü 
   
   if ( string2 != Î ) // åñëè string2 - íå NULL, êîïèðîâàòü 
      strcpy( sPtr, string2 ); // êîïèðîâàòü ëèòåðàë â îáúåêò 
   else // åñëè string2 - NULL, ñäåëàòü this ïóñòîé ñòðîêîé 
        sPtr[ 0 ] = ''; // ïóñòàÿ ñòðîêà 
} // êîíåö ôóíêöèè setString 
 
// ïåðåãðóæåííàÿ îïåðàöèÿ âûâîäà 
ostream &operator<<( îstream &output, const String &s ) 
{ 
   output << s.sPtr; 
   return output; // ðàçðåøàåò êàñêàäèðîâàíèå 
} // êîíåö ôóíêöèè operator<< 
 
// ïåðåãðóæåííàÿ îïåðàöèÿ ââîäà 
istream &operator>>( istream &input, String &s ) 
{ 
   char temp[ 100 ]; // áóôåð äëÿ õðàíåíèÿ ââîäà 
   input >> setw( 100 ) >> temp; 
   s = temp; // èñïîëüçîâàòü îïåðàöèþ ïðèñâàèâàíèÿ êëàññà String 
   return input; // ðàçðåøàåò êàñêàäèðîâàíèå 
} // êîíåö ôóíêöèè operator>>
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Ðèñ. 11.11: fig11_11.cpp 
// Òåñòîâàÿ ïðîãðàììà äëÿ êëàññà String. 
#include <iostream> 
using std::cout; 
using std::endl; 
using std::boolalpha; 
 
#include "String.h" 
 
int main() 
{ 
   String s1( "happy" ); 
   String s2( " birthday" ); 
   String s3; 
   
   // òåñòèðîâàòü ïåðåãðóæåííûå îïåðàöèè ðàâåíñòâà è îòíîøåíèé 
   cout << "s1 is "" << s1 << ""; s2 is "" << s2 
   << ""; s3 is "" << s3 << '"' 
   << boolalpha << "nnThe results of comparing s2 and s1:" 
   << "ns2 == s1 yields " << ( s2 == s1 ) 
   << "ns2 != s1 yields " << ( s2 != s1 ) 
   << "ns2 > s1 yields " << ( s2 > s1 ) 
   << "ns2 < s1 yields " << ( s2 < s1 ) 
   << "ns2 >= s1 yields " << ( s2 >= s1 ) 
   << "ns2 <= s1 yields " << ( s2 <= s1 ); 
   
   
   // òåñòèðîâàòü ïåðåãðóæåííóþ îïåðàöèþ "ïóñòî" (!) êëàññà String 
   cout << "nnTesting !s3:" << endl;
    
   if ( !s3 ) 
   { 
      cout << "s3 is empty; assigning s1 to s3;" << endl; 
      s3 = s1; // ïðîòåñòèðîâàòü ïåðåãðóæåííîå ïðèñâàèâàíèå 
      cout << "s3 is "" << s3 << """; 
   } // êîíåö if 
   
   // òåñòèðîâàòü ïåðåãðóæåííóþ îïåðàöèþ êîíêàòåíàöèè ñòðîê 
   cout << "nns1 += s2 yields si = "; 
   s1 += s2; // ïðîòåñòèðîâàòü ïåðåãðóæåííóþ êîíêàòåíàöèþ 
   cout << s1; 
   
   // òåñòèðîâàòü êîíñòðóêòîð ïðåîáðàçîâàíèÿ 
   cout << "nns1 += " to you" yields" << endl; 
   s1 += " to you"; // test conversion constructor 
   cout << "s1 = " << s1 << "nn"; 
   
   // òåñòèðîâàòü îïåðàöèþ âûçîâà () äëÿ ïîäñòðîêè 
   cout << "The substring of s1 starting atn" 
   << "location 0 for 14 characters, s1(0, 14), is:n" 
   << s1( 0, 14 ) << "nn"; 
   
   // òåñòèðîâàòü ñëó÷àé ïîäñòðîêè "äî êîíöà ñòðîêè" 
   cout << "The substring of s1 starting atn" 
   << "location 15, s1 (15), is: " 
   << s1( 15 ) << "nn"; 
   
   // òåñòèðîâàòü êîíñòðóêòîð êîïèè 
   String *s4Ptr = new String( s1 ); 
   cout << "n*s4Ptr = " << *s4Ptr << "nn"; 
   
   // òåñòèðîâàòü îïåðàöèþ ïðèñâàèâàíèÿ (=) ñ ñàìîïðèñâàèâàíèåì 
   cout << "assigning *s4Ptr to *s4Ptr" << endl; 
   *s4Ptr = *s4Ptr; // ïðîòåñòèðîâàòü ïåðåãðóæåííîå ïðèñâàèâàíèå 
   cout << "*s4Ptr = " << *s4Ptr << endl; 
   
   // òåñòèðîâàòü äåñòðóêòîð 
   delete s4Ptr; 
   
   // òåñòèðîâàòü èñïîëüçîâàíèå èíäåêñàöèè äëÿ ïîëó÷åíèÿ lvalue 
   s1[ 0 ] = 'Í'; 
   s1[ 6 ] = 'Â'; 
   cout << "ns1 after s1[0] = 'H' and s1[6] = 'B' is: " 
   << s1 << "nn"; 
   
   // òåñòèðîâàòü âûõîä èíäåêñà èç äèàïàçîíà 
   cout << "Attempt to assign 'd' to s1[30] yields:" << endl; 
   s1[ 30 ] = 'd'; // ÎØÈÁÊÀ: èíäåêñ âíå äèàïàçîíà 
   return 0; 
} // êîíåö main



0



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

18.07.2014, 15:30

7

Ошибки какие-то странные: в нескольких местах, вместо английской o русская (ostream), вместо ноля — буква О (if ( string2 != 0 )). Откуда взяли метод void String::setstring( const char *string2 ) (в String.срр)? В классе такого нет, есть setString.



0



327 / 230 / 55

Регистрация: 30.05.2014

Сообщений: 682

18.07.2014, 17:50

8

Цитата
Сообщение от alsav22
Посмотреть сообщение

Ошибки какие-то странные

Да копипаста из pdf как пить дать. В выходные поправлю, если время будет.



0



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

18.07.2014, 19:09

9

Да я, в общем-то, поправил.



1



12 / 12 / 0

Регистрация: 31.08.2011

Сообщений: 458

18.07.2014, 23:57

 [ТС]

10

Цитата
Сообщение от uglyPinokkio
Посмотреть сообщение

Да копипаста из pdf как пить дать.

да, оно самое из оттуда самого ). Я с книги примеры копирую себе в компилятор и ,изучая С++, параллельно смотрю на живом выполнении программы. Но вот копипаста из пдф не все символы правильно распознает. Вместо s1 может написать si.

Цитата
Сообщение от alsav22
Посмотреть сообщение

вместо английской o русская (ostream)

а как ты это увидел? Я даже и не думал, что копирование так будет происходить.

Цитата
Сообщение от alsav22
Посмотреть сообщение

Откуда взяли метод void String::setstring( const char *string2 ) (в String.срр)?

да, это ошибка. Там с большой буквы надо, как ты написал.

Добавлено через 3 минуты

Цитата
Сообщение от alsav22
Посмотреть сообщение

Да я, в общем-то, поправил.

а как ты поправил? Я например, вижу один вариант как это можно сделать. В одном окне открыть оригинал а во втором заново напечатать самому, глядя на первый. Тогда все символы точно будут в нужном языке.



0



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

19.07.2014, 00:24

11

Цитата
Сообщение от Тимур05
Посмотреть сообщение

а как ты это увидел?

Догадался (с подсказкой компилятора).

Цитата
Сообщение от Тимур05
Посмотреть сообщение

а как ты поправил?

Заменил букву.



0



327 / 230 / 55

Регистрация: 30.05.2014

Сообщений: 682

19.07.2014, 05:33

12

Цитата
Сообщение от Тимур05
Посмотреть сообщение

да, оно самое из оттуда самого ). Я с книги примеры копирую себе в компилятор и ,изучая С++, параллельно смотрю на живом выполнении программы. Но вот копипаста из пдф не все символы правильно распознает. Вместо s1 может написать si.

Не копируй,набирай руками.



0



Понравилась статья? Поделить с друзьями:
  • Error macro min requires 2 arguments but only 1 given
  • Error macro date might prevent reproducible builds werror date time
  • Error mac did not verify
  • Error m587 failed to add ssid to remembered list another spi transfer is pending
  • Error m587 expected string expression