Opened 6 years ago

Last modified 5 years ago

#12554 new Bugs

boost/core/typeinfo.hpp creates unwanted strings in release binary

Reported by: Lev Sch <Zorechfan@…> Owned by: jsiek
Milestone: Website 1.X Component: tokenizer
Version: Boost 1.62.0 Severity: Optimization
Keywords: Cc:

Description

If a program is compiled for a production build then strings are created in program binary. Location where the strings are created: boost/core/typeinfo.hpp -> boost::core::detail::core_typeid_::name -> BOOST_CURRENT_FUNCTION.

Current behavior has two drawbacks for a production version of a program:

  1. binary program file size become larger
  2. code symbols are present in production version of a program

Five minutes proposed solution from me is replace function "name" by

Code highlighting:

  static char const * name()
    {
#ifdef NDEBUG
        return "";
#else
        return BOOST_CURRENT_FUNCTION;
#endif
    }

Sorry for English...

Thank you for attention.

Change History (13)

comment:1 by Lev Sch <Zorechfan@…>, 6 years ago

Component: Nonecore
Owner: set to Peter Dimov

comment:2 by Lev Sch <Zorechfan@…>, 6 years ago

At this morning, I have created minimal steps to reproduce.

  1. Create "Win32 Console Application" in Microsoft Visual Studio with default settings
  2. select "Release" configuration to build
  3. add preprocessor include path to boost
  4. add preprocessor definition BOOST_NO_TYPEID
  5. disable RTTI by compiler flag
  6. replace content of file that contains "main" function by:

    Code highlighting:

    // ConsoleApplication2.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    #include <boost/shared_ptr.hpp>
    #include <boost/make_shared.hpp>
    
    int main()
    {
      class MyFavoriteClass {
      public:
        void print()
        {
          printf("HelloWorldABC\n");
        }
      };
      //boost::shared_ptr<MyFavoriteClass> ptr(new MyFavoriteClass());
      boost::shared_ptr<MyFavoriteClass> ptr = boost::make_shared<MyFavoriteClass>();
      ptr->print();
      
      return 0;
    }
    
  7. build application
  8. (!) ConsoleApplication2.exe will contain "MyFavoriteClass"
  9. In file boost\core\typeinfo.hpp replace BOOST_CURRENT_FUNCTION by "" (empty string)
  10. build application
  11. (!) ConsoleApplication2.exe will NOT contain "MyFavoriteClass"

comment:3 by Peter Dimov, 6 years ago

We could add a dedicated macro to make name() return an empty string or something like "(unknown)". NDEBUG doesn't seem right here because programs could rely on name() in release builds (for logging, exceptions, and so on.)

comment:4 by Lev Sch <Zorechfan@…>, 6 years ago

Dedicated macro is suitable for me.

comment:5 by Lev Sch <Zorechfan@…>, 6 years ago

In last days I was thinking in background about this ticket.

The example program (from second comment) does not use string, but string is present in binary file.

Is there rule violation: http://www.stroustrup.com/crc.pdf -> "Low-level programming support rules" -> "What you don’t use, you don’t pay for (zero-overhead rule)." ?

comment:6 by Peter Dimov, 6 years ago

The reason is that BOOST_TYPEID emulates the built-in typeid operator, which returns a reference to typeinfo, which is a non-template class. So typeinfo::name() has to be present. If BOOST_TYPEID could return typeinfo<T> instead, name() would not be instantiated unless used. But it can't.

Why are you defining BOOST_NO_TYPEID by hand under MSVC though? It's not required.

comment:7 by Lev Sch <Zorechfan@…>, 6 years ago

If only this line is used

printf("%s\n",typeid(MyFavoriteClass)==typeid(MyFavoriteClass) ? "true" : "false");

and RTTI is disabled then binary file will contain this string:

.?AVMyFavoriteClass@?1??main@@YAHXZ@

I do not want these lines and I have no influence to compiler. I disabled RTTI for my project and does not use "typeid" operator. Another libraries should not use typeid also, to prevent these strings. So, I disabled usage of typeid by Boost by defining BOOST_NO_TYPEID.

I use own implementation of typeid that does not generate these strings.

comment:8 by Peter Dimov, 6 years ago

I wonder whether the right fix for this isn't to add a macro that disables BOOST_CURRENT_FUNCTION altogether instead of just this use of it. It seems to me that if you want this use to not put a string into the executable, you probably don't want any other uses to emit strings either.

comment:9 by Lev Sch <Zorechfan@…>, 6 years ago

Summary:

  1. my code must not put code strings into an executable
  2. third party code must not put my code strings into an executable
  3. third party code can put third party code strings into an executable, but it is not desired

I'm developing under Android also. Every string is doubled (x86 and Arm platforms).

Currently, after patch was applied from Description, following strings are put into executable also (Android x86):

  boost::filesystem::canonical
  boost::filesystem::copy
  boost::filesystem::copy_directory
  boost::filesystem::copy_file
  boost::filesystem::create_directories
  boost::filesystem::create_directory
  boost::filesystem::create_directory_symlink
  boost::filesystem::create_hard_link
  boost::filesystem::create_symlink
  boost::filesystem::current_path
  boost::filesystem::equivalent
  boost::filesystem::file_size
  boost::filesystem::hard_link_count
  boost::filesystem::is_empty
  boost::filesystem::last_write_time
  boost::filesystem::permissions
  boost::filesystem::read_symlink
  boost::filesystem::relative
  boost::filesystem::remove
  boost::filesystem::remove_all
  boost::filesystem::rename
  boost::filesystem::resize_file
  boost::filesystem::space
  boost::filesystem::status
  boost::filesystem::temp_directory_path
  boost::filesystem::weakly_canonical
  boost::filesystem::directory_iterator::construct
  boost::filesystem::directory_iterator::operator++
  boost::condition_variable::wait failed in pthread_cond_wait
  boost unique_lock has no mutex
  boost unique_lock doesn't own the mutex
  boost unique_lock owns already the mutex
  boost: mutex lock failed in pthread_mutex_lock
  boost::condition_variable::do_wait_until failed in pthread_cond_timedwait
  boost::exception_ptr boost::exception_detail::get_static_exception_object() [Exception = boost::exception_detail::bad_alloc_]
  C:\lib\boost_1_62_0\boost/exception/detail/exception_ptr.hpp
  boost::exception_ptr boost::exception_detail::get_static_exception_object() [Exception = boost::exception_detail::bad_exception_]
  boost:: mutex constructor failed in pthread_mutex_init
  boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init
  boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init
  static const char *boost::detail::ctti<boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<char> > >::n() [T = boost::algorithm::detail::token_finderF<boost::algorithm::detail::is_any_ofF<char> >]
  call to empty boost::function
  bad lexical cast: source type value could not be interpreted as target
  N5boost18thread_interruptedE
  N5boost9exceptionE
  N5boost16exception_detail10clone_baseE
  N5boost16exception_detail10clone_implINS0_10bad_alloc_EEE
  N5boost16exception_detail10bad_alloc_E
  N5boost16exception_detail10clone_implINS0_14bad_exception_EEE
  N5boost16exception_detail14bad_exception_E

Following compiler flags were used:

      "-DANDROID",
      "-DANDROID_NDK",
      "-DBOOST_NO_TYPEID",
      "-DBOOST_FILESYSTEM_NO_DEPRECATED",
      "-DLOKI_OBJECT_LEVEL_THREADING",
      "-DBOOST_ENABLE_ASSERT_DEBUG_HANDLER",
      "-DBOOST_EXECUTION_CONTEXT=1",
      "-fPIC",
      "-fvisibility=hidden",
      "-fvisibility-inlines-hidden",
      "-ffunction-sections",
      "-fdata-sections",
      "-fno-rtti",
      "-g",
      "-Os",
      "-DNDEBUG",
      "-U_DEBUG",

comment:10 by Peter Dimov, 6 years ago

OK, I added a macro BOOST_DISABLE_CURRENT_FUNCTION in

https://github.com/boostorg/assert/commit/c67fe0a9249a304dc4ccdf5059999efc1e5ad267

This should take care of some of the strings.

comment:11 by Lev Sch <Zorechfan@…>, 6 years ago

Thank you!

comment:12 by Lev Sch <zorechfan@…>, 6 years ago

I've checked on 1.63. The fix works fine.

comment:13 by anonymous, 5 years ago

Component: coretokenizer
Milestone: To Be DeterminedWebsite 1.X
Owner: changed from Peter Dimov to jsiek
Severity: ProblemOptimization
Note: See TracTickets for help on using tickets.