News:

When registered with our forums, feel free to send a "here I am" post here to differ human beings from SPAM bots.

Main Menu

std::endl : wrong completion

Started by killerbot, August 26, 2010, 12:07:14 PM

Previous topic - Next topic

killerbot

For the first time (I think), CB::CC allowed me to complete std::endl. But it putted :
std::endl()

The "()" shouldn't be there.

blueshake

it is something related to auto assert "()",can you turn off this,and try again.if it work ,there maybe is something wrong with the parse for token "endl".
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

killerbot

note that this does not happen during the completion of std::cout !

ollydbg

Quote from: killerbot on August 26, 2010, 10:02:13 PM
note that this does not happen during the completion of std::cout !
simple answer:
cout is regarded as a variable, and endl is regarded as a function( several token named "endl" exist under std namespace, but all of them were functions). see the image below:





This is due some parser problem... let me check it if I have time. :D

If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Loaden

Let's see iostream file (LINE: 536)
Quote// [27.6.2.7] standard basic_ostream manipulators
 /**
  *  @brief  Write a newline and flush the stream.
  *
  *  This manipulator is often mistakenly used when a simple newline is
  *  desired, leading to poor buffering performance.  See
  *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 for more
  *  on this subject.
 */
 template<typename _CharT, typename _Traits>
   inline basic_ostream<_CharT, _Traits>&
   endl(basic_ostream<_CharT, _Traits>& __os)
   { return flush(__os.put(__os.widen('\n'))); }
This is a function!

But in:ostream.tcc (LINE: 361 or 384)
Quote#if _GLIBCXX_EXTERN_TEMPLATE
 extern template class basic_ostream<char>;
 extern template ostream& endl(ostream&);
 extern template ostream& ends(ostream&);
Here is a variable.

ollydbg

Quote from: Loaden on August 27, 2010, 05:57:10 AM
But in:ostream.tcc (LINE: 361 or 384)
Quote#if _GLIBCXX_EXTERN_TEMPLATE
 extern template class basic_ostream<char>;
 extern template ostream& endl(ostream&);
 extern template ostream& ends(ostream&);
Here is a variable.

our parser just recognize this "endl" as a function, because it has some grammar mode:

AAAA BBBB();
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Loaden

#6
Quote from: ollydbg on August 27, 2010, 06:55:04 AM
Quote from: Loaden on August 27, 2010, 05:57:10 AM
But in:ostream.tcc (LINE: 361 or 384)
Quote#if _GLIBCXX_EXTERN_TEMPLATE
 extern template class basic_ostream<char>;
 extern template ostream& endl(ostream&);
 extern template ostream& ends(ostream&);
Here is a variable.

our parser just recognize this "endl" as a function, because it has some grammar mode:

AAAA BBBB();


Looks can only judge of the special?
QuoteIndex: src/plugins/codecompletion/codecompletion.cpp
===================================================================
--- src/plugins/codecompletion/codecompletion.cpp   (revision 6543)
+++ src/plugins/codecompletion/codecompletion.cpp   (working copy)
@@ -790,7 +790,8 @@
                 items.Add(tmp);
                 if (autoAddParentheses && token->m_TokenKind == tkFunction)
                 {
-                    m_SearchItem[token->m_Name] = token->m_Args.size() - 2;
+                    if (token->m_Name != _T("endl"))
+                        m_SearchItem[token->m_Name] = token->m_Args.size() - 2;
                 }
                 if (token->m_TokenKind == tkNamespace && token->m_Aliases.size())
                 {

[attachment deleted by admin]

eranif

std::endl *is* a function.

When people are typing std::endl they are actually passing the pointer of the function to the 'operator <<' of class basic_ostream

__ostream_type&
      operator<<(__ostream_type& (*__pf)(__ostream_type&))


The same is true for all other similar methods, like std::hex, std::oct, std::dec etc
So if you are going to special handle the 'endl' case, make sure you handle the other methods as well (hex, dec, oct etc.)

Eran

ollydbg

Quote from: eranif on August 27, 2010, 07:55:16 AM
std::endl *is* a function.

When people are typing std::endl they are actually passing the pointer of the function to the 'operator <<' of class basic_ostream

__ostream_type&
      operator<<(__ostream_type& (*__pf)(__ostream_type&))


The same is true for all other similar methods, like std::hex, std::oct, std::dec etc
So if you are going to special handle the 'endl' case, make sure you handle the other methods as well (hex, dec, oct etc.)

Eran


Thanks eran for your help.
So, my personal question is: how does Codelite deal with this kind of problem??
thanks.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

eranif

QuoteSo, my personal question is: how does Codelite deal with this kind of problem??
I am not :D

The same as codeblocks:
when user types std::endl -> codelite adds the () and shows the function tip. I never find it a problem since in codelite if I delete the open brace, the closing brace is also deleted

Eran

ollydbg

Quote from: eranif on August 27, 2010, 08:02:19 AM
QuoteSo, my personal question is: how does Codelite deal with this kind of problem??
I am not :D

OK, Now we have two ways:
One is like codelite does
QuoteThe same as codeblocks:
when user types std::endl -> codelite adds the () and shows the function tip. I never find it a problem since in codelite if I delete the open brace, the closing brace is also deleted
The other is special handling like: (endl, hex, dec, oct etc)

thanks. :D
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

ollydbg

maybe, a better way is :

checking the "<<" can accept a function pointer, then we can avoid adding "()" in this case. But it is too complex  :D
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

MortenMacFly

Quote from: Loaden on August 27, 2010, 07:06:16 AM
Looks can only judge of the special?
No good. Imagine you have a local variable / method with this name than endl has a different meaning and appending the brackets might be desired. In addition: actually this codecompletion should not have any language specific elements at all... ;-)
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

Loaden

Quote from: MortenMacFly on August 27, 2010, 08:12:57 AM
Quote from: Loaden on August 27, 2010, 07:06:16 AM
Looks can only judge of the special?
No good. Imagine you have a local variable / method with this name than endl has a different meaning and appending the brackets might be desired. In addition: actually this codecompletion should not have any language specific elements at all... ;-)
Well, we still remain the same.

Loaden

Quote from: ollydbg on August 27, 2010, 08:11:26 AM
maybe, a better way is :

checking the "<<" can accept a function pointer, then we can avoid adding "()" in this case. But it is too complex  :D
I think this is not possible!