473,382 Members | 1,658 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Whats the standard here and why?

I am attaching this simple code snippet which compiles fine with MS C++ compiler v15 ( which comes with Visual C++ 8 ) but fails with MS C++ compiler v16 ( Visual C++ 10 ) and g++ from MingW.

The long code is below, here is the relevant part and why I think the compiler does not like it.

I have a static member function in class t_threads as so-
Expand|Select|Wrap|Line Numbers
  1. static void run()
  2. {
  3. for( set<t_thread>::iterator ix = _s_pobj->_threads.begin(); ix != _s_pobj->_threads.end(); ++ix )
  4. (*ix).run();
  5. }
  6.  
t_threads manages a set of t_thread objects. In the above function, it starts the threads it manages. The t_thread::run function is non-const ( of course, since it changes the state of the t_thread object ). The iterator "ix" is also non-const. But the compiler promotes the iterator to a const because t_threads::run is a static member function.

The error from g++ is -

w.cpp: In static member function `static void t_threads::run()':
w.cpp:95: error: passing `const t_thread' as `this' argument of `void t_thread::run()' discards qualifiers


This should be allowed, IMO. I need the t_threads::run function to be static because of the way I call it in main(). See below. Of course I could change the code but this is just a small part of a much larger system and I have to change similar constructs in numerous places and I am going to stick with MS C++ compiler v15 for the time being.

The sample code-

Expand|Select|Wrap|Line Numbers
  1. #include <stdlib.h>
  2. #include <assert.h>
  3.  
  4. #include <iostream>
  5. #include <string>
  6. #include <set>
  7.  
  8. using namespace std;
  9.  
  10. // the t_thread object
  11.  
  12. class t_thread
  13. {
  14. public:
  15.  
  16. t_thread( int _tid )
  17. : tid_ (_tid), run_(false)
  18. {}
  19. void run() { run_ = true; cout << "run(" << tid_ << ") running!\n"; }
  20.  
  21. void dump() const { cout << "dump(" << tid_ << ") run=" << run_ << "\n"; }
  22.  
  23. bool operator<( const t_thread& t2 ) const {
  24. return tid_ < t2.tid_;
  25. }
  26.  
  27. private:
  28.  
  29. bool run_;
  30. int tid_;
  31. };
  32.  
  33. // the t_threads object
  34.  
  35. class t_threads
  36. {
  37. public:
  38.  
  39. static int initialize( string& serr )
  40. {
  41. // check for multiple initialization
  42. if( _s_initialized ) {
  43. serr = "t_threads: multiple initialization not allowed!";
  44. return -1;
  45. }
  46.  
  47. // create the global t_threads object
  48. _s_pobj = new t_threads();
  49.  
  50. if( !_s_pobj ) {
  51. serr = "t_threads: cannot create new t_threads!";
  52. return -1;
  53. }
  54.  
  55. // remember initialization
  56. _s_initialized = true;
  57.  
  58. return 0;
  59. }
  60.  
  61. static void finalize()
  62. {
  63. delete _s_pobj;
  64. _s_initialized = false;
  65. }
  66.  
  67. static const t_threads& _this()
  68. {
  69. return *_s_pobj;
  70. }
  71.  
  72. static void dump()
  73. {
  74. for( set<t_thread>::const_iterator ixc = _s_pobj->_threads.begin(); ixc != _s_pobj->_threads.end(); ++ixc )
  75. (*ixc).dump();
  76. }
  77.  
  78. static const set<t_thread>& threads()
  79. {
  80. return _s_pobj->_threads;
  81. }
  82.  
  83. static int create( int _tid )
  84. pair<set<t_thread>::iterator,bool> pair_ = _s_pobj->_threads.insert( t_thread( _tid ) );
  85.  
  86. assert( pair_.second );
  87.  
  88. return 0;
  89. }
  90.  
  91. static void run()
  92. for( set<t_thread>::iterator ix = _s_pobj->_threads.begin(); ix != _s_pobj->_threads.end(); ++ix )
  93. (*ix).run();
  94. }
  95.  
  96. private:
  97.  
  98. t_threads() {}
  99. t_threads( const t_threads& );
  100. t_threads& operator=( const t_threads& );
  101.  
  102. set<t_thread> _threads;
  103.  
  104. static t_threads* _s_pobj;
  105. static bool _s_initialized;
  106. };
  107.  
  108. t_threads* t_threads::_s_pobj = NULL;
  109. bool t_threads::_s_initialized = false;
  110.  
  111. // main section
  112.  
  113. int main(int argc, char **argv)
  114. {
  115. string serr;
  116. if( -1 == t_threads::initialize(serr) ) {
  117. cout << "main: t_threads::initialize error " << serr;
  118. return -1;
  119. }
  120.  
  121. for( int i = 0; i < atoi(argv[1]); i++ )
  122. if( -1 == t_threads::create(i)) {
  123. cout << "main: t_threads::create error " << serr;
  124. return -1;
  125. }
  126.  
  127. t_threads::dump();
  128. t_threads::run();
  129. t_threads::dump();
  130.  
  131. t_threads::finalize();
  132.  
  133. return 0;
  134. }
  135.  
Jun 3 '10 #1
2 1294
Banfa
9,065 Expert Mod 8TB
Well its a bit complicated and related to the fact you are using a set.

In the newer MS C++ and gcc set<>::iterator is defined as a constant iterator and I suspect that is a specific design choice people have made.

However all iterators types are implementation defined so the fact that the definition has changed from on version of MS C++ to another and is different in GCC is not actually breaking the standard at all. It can happen, the standard says so.

I suspect (think I have seen said elsewhere) that the reason for making all iterators constant is that in a set the key is the value. However the set is sorted on the key and if you allowed the key to change that would imply a different sort order. That would mean the code would have to be able to know and alterations to the key and reorder the list when they happened.

That last bit isn't possible so the conclusion is that the key must be constant (actually a fairly normal assumption for a keyed table) however since the key is the value that means the value is constant too and so everyone has change all set iterators to be constant.

gcc definitions
Expand|Select|Wrap|Line Numbers
  1.      typedef typename _Rep_type::const_iterator            iterator;
  2.       typedef typename _Rep_type::const_iterator            const_iterator;
  3.  

The conclusion, set<> is uniquely not suited for the purpose you are trying to use it for because it is a set of constant keys. Personally I would use a list, or if you really want to use an associative container rather than a sequence a map.
Jun 3 '10 #2
Thanks for the explanation. It makes sense.
Jun 3 '10 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

52
by: piaseckiac | last post by:
I am producing a website on air and need a link to change the entire website from standard to metric for temperature, pressure, miles-kilometers, and volume. Thank you.
2
by: Robert Smith | last post by:
Why doesnt this code work???? it just stops at the socket() and does not print HI. why is this? #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h>...
6
by: thesushant | last post by:
hi, whats the use of third argument to main( ), i.e. environmental parameters.... if i am not wrong ? 1st 1 is argc 2nd is argv and what bout the 3rd 1??????????? sushant
5
by: kernel.lover | last post by:
hello, I want to know if a fuction say malloc is declared as void *malloc() then whats the significance of void here. Does void * is used when function has the flexibility to return any type of...
19
by: anonymouse | last post by:
Is it possible to have C# run in an unmanaged environemnt if somebody should decide to implemnent it this way? Its possible to code C# projects without any dependancy on the libraries at all...
5
by: Alexandre Martins | last post by:
Provider=Microsoft.Jet.OLEDB.4.0;UserId=Admin;Password=teste;Data Source=C:\Inetpub\wwwroot\inktoner\dados\db_inktoner.mdb;Persist Security Info=True I can't connect in my database ! whats...
4
by: markrush | last post by:
if i have 2 datasources with different table names and column headers that i want to merge i.e. "ptitle" and "name" whats the best way of doing this? are there any standard routines or should i use...
20
by: Snis Pilbor | last post by:
Whats the point of making functions which take arguments of a form like "const char *x"? It appears that this has no effect on the function actually working and doing its job, ie, if the function...
14
by: nobrow | last post by:
Yes I know what lvalue means, but what I want to ask you guys about is what are all valid lvalues ... a *a a *(a + 1) .... What else?
270
by: jacob navia | last post by:
In my "Happy Christmas" message, I proposed a function to read a file into a RAM buffer and return that buffer or NULL if the file doesn't exist or some other error is found. It is interesting...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.