-4

(This is not a duplicate of another question since in the other one the question is about the compilation issue (where somebody suggested to implement a constructor), and here there is an specific question about how to implement that constructor manually)

In order to compile the following program with GCC 4.9.2, It has to be modified. I have to implement the constructor manually and I dont know how to do it.

The line 6 is causing trouble and is the one that needs to be modified: 'TabStats::TabStats(TabStats&& other) noexcept = default;'

As a condition, the no-except specifier cant be removed.

SOURCE CODE:

#include "browser/resource_coordinator/tab_stats.h"
#include "build/build_config.h"    
namespace resource_coordinator {
TabStats::TabStats() = default;
TabStats::TabStats(const TabStats& other) = default;
TabStats::TabStats(TabStats&& other) noexcept = default;
TabStats::~TabStats() {}
TabStats& TabStats::operator=(const TabStats& other) = default;
}  // namespace resource_coordinator

tab_stats.h is included below:

#ifndef BROWSER_RESOURCE_COORDINATOR_TAB_STATS_H_
#define BROWSER_RESOURCE_COORDINATOR_TAB_STATS_H_
#include <stdint.h>
#include <vector>
#include "base/process/process.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "build/build_config.h"

namespace content {
class RenderProcessHost;
}  // namespace content

namespace resource_coordinator {

struct TabStats {
  TabStats();
  TabStats(const TabStats& other);
  TabStats(TabStats&& other) noexcept;
  ~TabStats();

  TabStats& operator=(const TabStats& other);

  bool is_app = false;            // Browser window is an app.
  bool is_internal_page = false;  // Internal page, such as NTP or Settings.
  // Playing audio, accessing cam/mic or mirroring display.
  bool is_media = false;
  bool is_pinned = false;
  bool is_in_visible_window = false;
  bool is_in_active_window = false;
  // Whether this is the active tab in a browser window.
  bool is_active = false;
  bool is_discarded = false;
  // User has entered text in a form.
  bool has_form_entry = false;
  int discard_count = 0;
  bool has_beforeunload_handler = false;
  base::TimeTicks last_active;
  base::TimeTicks last_hidden;
  content::RenderProcessHost* render_process_host = nullptr;
  base::ProcessHandle renderer_handle = 0;
  int child_process_host_id = 0;
  base::string16 title;
#if defined(OS_CHROMEOS)
  int oom_score = 0;
#endif
  int64_t tab_contents_id = 0;  // Unique ID per WebContents.
  bool is_auto_discardable = true;
};

typedef std::vector<TabStats> TabStatsList;

}  // namespace resource_coordinator

#endif  // BROWSER_RESOURCE_COORDINATOR_TAB_STATS_H_

This is the compilation error Im getting (I removed many flags to make this shorter):

[20689/29018] CXX obj/chrome/browser/browser/tab_stats.o
FAILED: obj/chrome/browser/browser/tab_stats.o 
g++ -MMD -MF obj/chrome/browser/browser/tab_stats.o.d -DUSE_LIBSECRET -DV8_DEPRECATION_WARNINGS -DUSE_UDEV -DUSE_AURA=1 -DUSE_PANGO=1 -DUSE_CAIRO=1 -DUSE_GLIB=1 -DUSE_NSS_CERTS=1 -DUSE_X11=1 -DNO_TCMALLOC -DDISABLE_NACL -DFULL_SAFE_BROWSING -DSAFE_BROWSING_CSD -DSAFE_BROWSING_DB_LOCAL -DCHROMIUM_BUILD -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D_FORTIFY_SOURCE=2 -DNDEBUG -DUSE_CUPS -DUSE_GNOME_KEYRING -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32 -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_26 -DUSE_GLX -DSK_SUPPORT_GPU=1 -DV8_USE_EXTERNAL_STARTUP_DATA -DWEBRTC_CHROMIUM_BUILD -DWEBRTC_POSIX -DWEBRTC_LINUX -DHUNSPELL_STATIC --param=ssp-buffer-size=4 -fstack-protector -Wno-builtin-macro-redefined -D__DATE__= -D__TIME__= -D__TIMESTAMP__= -funwind-tables -fPIC -pipe -pthread -m32 -msse2 -mfpmath=sse -mmmx -Wall -O2 -g0 -fvisibility=hidden -DLIBXML_STATIC= -std=gnu++11 -nostdinc++ -isystem../../buildtools/third_party/libc++/trunk/include -isystem../../buildtools/third_party/libc++abi/trunk/include -Wno-narrowing -fno-rtti -fno-exceptions -fvisibility-inlines-hidden -c ../../chrome/browser/resource_coordinator/tab_stats.cc -o obj/chrome/browser/browser/tab_stats.o
../../chrome/browser/resource_coordinator/tab_stats.cc:14:1: error: function 'resource_coordinator::TabStats::TabStats(resource_coordinator::TabStats&&)' defaulted on its redeclaration with an exception-specification that differs from the implicit declaration 'resource_coordinator::TabStats::TabStats(resource_coordinator::TabStats&&)'
 TabStats::TabStats(TabStats&& other) noexcept = default;

 ^
bari
  • 5
  • 1
  • 4
  • 1
    Have you tried putting the `default` specifier in the class *definition* instead? I.e. in the header file? – Some programmer dude Nov 01 '17 at 08:44
  • By the way, if all constructors, destructors and the copy-assignment operator are to be defaulted, why have them at all? Can't you just remove them and let the compiler implicitly declare and define them? – Some programmer dude Nov 01 '17 at 08:47
  • uhm, I cannot reproduce the problem, [this](https://godbolt.org/g/hMYAii) compiles in gcc 4.9.2 – Massimiliano Janes Nov 01 '17 at 08:48
  • @Some programmer dude The resulting code would be something like this or I got you wrong? namespace content { class RenderProcessHost = default; } // namespace content – bari Nov 01 '17 at 08:49
  • No, like `struct TabStats { TabStats() = default; ... };` – Some programmer dude Nov 01 '17 at 08:50
  • 4
    [You've asked this question yesterday](https://stackoverflow.com/questions/47032077/noexcept-default-compilation-error). – user7860670 Nov 01 '17 at 08:57
  • @Massimiliano Janes I have added to the question the compilation failure Im getting... this program is part of the chromium source code – bari Nov 01 '17 at 09:02
  • @VTT yes, but I still dont know how to do that... I didnt write that code... that's part of the chromium source code and in order to compile it I have to solve the question I posed... I dont know enough C language to implement a constructor... that's why Im asking for help – bari Nov 01 '17 at 09:04
  • 1
    Spamming identical questions will get you nowhere – Passer By Nov 01 '17 at 09:09
  • You may want to get some language knowledge before digging into large projects such as chromium. If (vanilla) chromium compilation fails it would be a better idea for you to submit a bug report to devs rather then asking here about writing code to fix non-reproducible problem. – user7860670 Nov 01 '17 at 09:26
  • Always declare constructors with '= default' (or '=delete', but that is a given) in the class body unless absolutely necessary.... For a constructor, that would be when the object is constructed in many (think hundreds/thousands) of places in the code base. Shame on the Chromium team. – Michaël Roy Nov 01 '17 at 09:45
  • Developers are aware of the bug and they recommend implementing manually the constructor... but the problem is when you dont know to do that. Here is the link where they say so, and this problem happens not only on android, but also on other linux distros like slax: https://bugs.chromium.org/p/chromium/issues/detail?id=706963 – bari Nov 01 '17 at 10:04
  • The easiest way to fix this code so it compiles it to simply remove the offending `noexcept` keyword. – Michaël Roy Nov 01 '17 at 14:01

1 Answers1

0

There are only two cases when you should have to write your own move constructor, and both of them make little sense:

  • when one of the base classes does not have move semantics, but then having move semantics for your derived class does not make sense at all.
  • when one of your class data member does not have move semantics, but then having move semantics for your class does not quite make sense.

Usually this would involve replacing the move operation by a copy.

A good starting point for writing your own move constructor, is to do what the the compiler does:

  • Call the move constructors of base classes (You must use std::move).
  • Call the move contructor of all class members. (use std::move).

ex:

struct A {};  // must have a move constructor, be it a default or not.

struct B : A
{
    B(B&& b) 
        : A(std::move(b))
        , data1_(std::move(b.data1_))
        , data2_(std::move(b.data2_))
    {}

    some_type        data1_;
    some_other_type  data2_;
};

Nothing exciting here, which is why the default works in most cases. Classes that cannot be moved are pretty rare.

Michaël Roy
  • 6,338
  • 1
  • 15
  • 19
  • So in order to fix the code, the constructor that would replace the line 6 would be something like this? (please correct me if Im wrong) TabStats::TabStats(TabStats&& other) noexcept : TabStats (std::move (other)) , TimeTicks_(std::move(other.TimeTicks_)) , ProcessHandle_ (std::move(other.ProcessHandle_ )) {} – bari Nov 01 '17 at 11:03
  • The code in your comment is infinitely recursive. In the example, I call the **base class** move constructor. All members must be moved 'by hand', including integers and the like, **every single one of them**. – Michaël Roy Nov 01 '17 at 13:32
  • Think of the move operation as a copy operation, but in which the source gets cannibalized. – Michaël Roy Nov 01 '17 at 13:38