Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Page 97, thread_local object #44

Closed
jpc0016 opened this issue Nov 14, 2019 · 3 comments
Closed

Page 97, thread_local object #44

jpc0016 opened this issue Nov 14, 2019 · 3 comments

Comments

@jpc0016
Copy link

@jpc0016 jpc0016 commented Nov 14, 2019

I cannot replicate results in Listing 4-7 with code in Listing 4-6. "Tracer" (line 17) is not recognized as an object when using "thread_local" keyword; however, "Tracer" is recognized when I use "static" keyword and I get the output in Listing 4-7. I added the "thread" header file, #include <thread>, and it still did not work. Both clang++ and g++ are up to date which should support threading. Help is appreciated.

@JLospinoso

This comment has been minimized.

Copy link
Owner

@JLospinoso JLospinoso commented Nov 15, 2019

Hi @jpc0016! Sorry you're having trouble with this. Is it possible that you haven't included the body of the Tracer class from Listing 4-5 into your code?

Have a look at https://github.com/JLospinoso/ccc/blob/master/chapter_4/listing_4_6.cpp. It should compile (example: https://wandbox.org/permlink/0MAvZho8A9F46In6)

@jpc0016

This comment has been minimized.

Copy link
Author

@jpc0016 jpc0016 commented Nov 15, 2019

Correct. It compiles but the thread_local object (t2) is not created. 'Tracer' is highlighted in first line but not in second. Although it compiles, the expected output is Thread-local variable constructed which I do not see.

help

@JLospinoso

This comment has been minimized.

Copy link
Owner

@JLospinoso JLospinoso commented Nov 18, 2019

Hi @jpc0016, I think you've uncovered a deeper issue! The standard actually says that the thread_local object's lifetime starts, at latest, on first use. This gives the compiler the option to emit initialization code at any point beginning with the thread's lifetime and as late as first use. All that's to say that you could achieve the listing's output in the following way:

#include <cstdio>

struct Tracer {
  Tracer(const char* name)
      : name{ name } {
    printf("%s constructed.\n", name);
  }
  ~Tracer() {
    printf("%s destructed.\n", name);
  }

  private:
  const char* const name;
};

static Tracer t1{ "Static variable" };
thread_local Tracer t2{ "Thread-local variable" };

int main() {
  const auto t2_ptr = &t2;
  printf("A\n");
  Tracer t3{ "Automatic variable" };
  printf("B\n");
  const auto* t4 = new Tracer{ "Dynamic variable" };
  printf("C\n");
}

I'll put together an Errata for this -- thanks for reporting and I hope you enjoy the rest of the book!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.