Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++ and threads: Messy code?

8 views
Skip to first unread message

Robert Schneider

unread,
Jun 25, 2003, 6:23:15 AM6/25/03
to
What do you think or suggest?

I use VC++ (and COM, so I cannot avoid object oriented programming).
When a method of an object creates a thread, this thread does not
belong to the object. Only global functions (which are not protected)
or static methods of the objects class (may be private/protected) can
serve as thread functions. This looks messy to me. I don't like that.
But is there an alternative? Or do I understand something wrong? I
know that also within the object oriented world there must be still
one function that is not object oriented: the main-function. Are
thread-functions similar to handle?

Please give me some informations or help.

BTW: Any recommended books or sites that discusses such topics in
generall (maybe in german)?

Thanks in advance.
Robert

Mariusz Plaskowicki

unread,
Jun 25, 2003, 6:46:08 AM6/25/03
to
You can pass 'this' to main function as a parameter and then call Your's
ThreadMain method using this.

--
Mariusz Plaskowicki
RTS
remove 'nospam' if You want to send a mail to me.

Michael Furman

unread,
Jun 25, 2003, 2:12:06 PM6/25/03
to

"Robert Schneider" <rschn...@testo.de> wrote in message
news:9a0110ad.0306...@posting.google.com...

> What do you think or suggest?
>
> I use VC++ (and COM, so I cannot avoid object oriented programming).
> When a method of an object creates a thread, this thread does not
> belong to the object. Only global functions (which are not protected)
> or static methods of the objects class (may be private/protected) can
> serve as thread functions. This looks messy to me. I don't like that.
> But is there an alternative? Or do I understand something wrong? I
> know that also within the object oriented world there must be still
> one function that is not object oriented: the main-function. Are
> thread-functions similar to handle?

It is not a problem. You can use static method as thread function and path
pointer to the class insttance as a parameter. For convinience I usually
define another non-static function and call it from the static one.
Example:

// Fragment of my thread class:
class Thread
{
public:
...........................
static void Do_(void * p_);
virtual void Do() = 0; // Non-static
thread function, to
//
to be defined in the derived class
........
};


// Starting the thread (from either constructor or some method of the class)
th = _beginthread(Do_, ssize, this);


// Fragment of the "Do_ method
void Thread::Do_(void * p_)
{
Thread * thread = static_cast<Thread *>(p_);
thread->Do();
........................................................
}

Michael

Pete Becker

unread,
Jun 26, 2003, 10:03:00 AM6/26/03
to
Michael Furman wrote:
>
> // Fragment of my thread class:
> class Thread
> {
> public:
> ...........................
> static void Do_(void * p_);
> virtual void Do() = 0; // Non-static

Thread::Do_ has C++ linkage; you can't reliably pass a pointer to it
into a C function. For that you need a function with extern "C" linkage:

extern "C" static void Do_(void * p_)
{
((Thead*)p_)->Do();
}

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Michael Furman

unread,
Jun 26, 2003, 2:07:39 PM6/26/03
to

"Pete Becker" <peteb...@acm.org> wrote in message
news:3EFAFD14...@acm.org...

> Michael Furman wrote:
> >
> > // Fragment of my thread class:
> > class Thread
> > {
> > public:
> > ...........................
> > static void Do_(void * p_);
> > virtual void Do() = 0; //
Non-static
>
> Thread::Do_ has C++ linkage; you can't reliably pass a pointer to it
> into a C function. For that you need a function with extern "C" linkage:

I believe it is not true:
1. I don't see in MSVC documentation any refering to _beginthread as to
"C" function.
2. Whether or not I can reliebly pass a pointer to C++ function to the MSVC
library function depends on the function - again I can't find any
limitation
in the MSVC C/C++ documentation.

I do not pass pointer to Do_ to my own "extern "C"" function (in wich case I
would agree with you) - I just pass it to the MSVC library function and
can/should
rely on their documentation.

(Note - for all C/C++ implementation I used to work with "C" and "C++"
linkages
for both regular functions and static member functions had only one
difference
I knew: name mangling. Though it could be differences related to exceptions
and of cause it does not have to be fo every C/C++ implementation)

Regards,
Michael

John Hickin

unread,
Jun 26, 2003, 3:32:07 PM6/26/03
to

"Michael Furman" <Michae...@Yahoo.com> wrote in message
news:bdfcpd$s7trg$1...@ID-122417.news.dfncis.de...

>
> "Pete Becker" <peteb...@acm.org> wrote in message
> >
> > Thread::Do_ has C++ linkage; you can't reliably pass a pointer to it
> > into a C function. For that you need a function with extern "C" linkage:
>
> I believe it is not true:
> 1. I don't see in MSVC documentation any refering to _beginthread as to
> "C" function.
> 2. Whether or not I can reliebly pass a pointer to C++ function to the
MSVC
> library function depends on the function - again I can't find any
> limitation
> in the MSVC C/C++ documentation.
>

Strictly speaking I have to agree but...

The Microsoft documentation for _beginthread states that the start routine
should use the __cdecl calling convention. OTOH, _beginthreadex and
CreateThread require a start routine that uses the __stdcall convention.
Since the default calling convention for C/C++ programs is __cdecl so you
don't have to specify anything extra when using _beginthread.

For reasons related to the race condition associated with the use of
_beginthread Microsoft says that it is safer to use _beginthreadex. In that
case, as __stdcall is not the default, it should be specified, something
like this:

unsigned __stdcall
StartThread( void* parameter ) {
static_cast<Thread*>(parameter)-> Do();
return 0;
}

The result returned by _beginthreadex should be casted to HANDLE and
(eventually) closed (CloseHandle()). It might be a good idea to code the
startup function like this (I've changed Thread:Do_'s signature):

HANDLE Thread::Do_( Thread* p ) {
HANDLE h = (HANDLE)__beginthreadex(...., &StartThread,
static_cast<void*>(p), ...);
return h;
}

That way the casts Thread* <--> void* are always going to work no matter
what kind of derived thread class you pass to Thread::Do_ and the caller
will be able to close the returned handle at a convenient time.

There is a useful write-up of _beginthread{, ex} here:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/
_crt__beginthread.2c_._beginthreadex.asp

There is lots of other stuff that I haven't mentioned.

BTW, for posix threads you will need to make the thread function extern "C",
although it will work on many platforms if omitted. Also, since posix
implementations are probably compiled with a c compiler, it may be unsafe to
allow an exception to pass out of the thread routine as the stack of those
functions might be damaged by an unwind:

// posix
extern "C"
void* StartThread( void* p ) {
try { static_cast<Thread*>(p) -> Do(); } // what compiler compiled the
_caller_ of StartThread? Don't know
catch(...) {} // so use
try/catch.
return 0;
}

Regards, John.


Pete Becker

unread,
Jun 26, 2003, 4:09:24 PM6/26/03
to
Michael Furman wrote:
>
> "Pete Becker" <peteb...@acm.org> wrote in message
> news:3EFAFD14...@acm.org...
> > Michael Furman wrote:
> > >
> > > // Fragment of my thread class:
> > > class Thread
> > > {
> > > public:
> > > ...........................
> > > static void Do_(void * p_);
> > > virtual void Do() = 0; //
> Non-static
> >
> > Thread::Do_ has C++ linkage; you can't reliably pass a pointer to it
> > into a C function. For that you need a function with extern "C" linkage:
>
> I believe it is not true:
> 1. I don't see in MSVC documentation any refering to _beginthread as to
> "C" function.

Every Win32 API function is marked extern "C" in the headers. If MS
doesn't document that, complain to them.

> 2. Whether or not I can reliebly pass a pointer to C++ function to the MSVC
> library function depends on the function - again I can't find any
> limitation
> in the MSVC C/C++ documentation.

The C++ language definition says that the behavior is undefined. If MS
tells you that they guarantee it will work, fine. Silence isn't enough.
And, of course, this isn't an MS forum, so MS-specific limitations need
to be called out.

>
> I do not pass pointer to Do_ to my own "extern "C"" function (in wich case I
> would agree with you) - I just pass it to the MSVC library function and
> can/should
> rely on their documentation.

And what in their documentation tells you what the behavior is when you
pass a function with C++ linkage to an API function that expects a
function with C linkage?

>
> (Note - for all C/C++ implementation I used to work with "C" and "C++"
> linkages
> for both regular functions and static member functions had only one
> difference
> I knew: name mangling. Though it could be differences related to exceptions
> and of cause it does not have to be fo every C/C++ implementation)
>

Nevertheless, the two are different, and some compilers will complain if
you try to mix them.

Michael Furman

unread,
Jun 26, 2003, 4:41:21 PM6/26/03
to
"Pete Becker" <peteb...@acm.org> wrote in message
news:3EFB52F4...@acm.org...

> Michael Furman wrote:
> >
> > "Pete Becker" <peteb...@acm.org> wrote in message
> > news:3EFAFD14...@acm.org...
> > > Michael Furman wrote:
> > > >
> > > > // Fragment of my thread class:
> > > > class Thread
> > > > {
> > > > public:
> > > > ...........................
> > > > static void Do_(void * p_);
> > > > virtual void Do() = 0; //
> > Non-static
> > >
> > > Thread::Do_ has C++ linkage; you can't reliably pass a pointer to it
> > > into a C function. For that you need a function with extern "C"
linkage:
> >
> > I believe it is not true:
> > 1. I don't see in MSVC documentation any refering to _beginthread as to
> > "C" function.
>
> Every Win32 API function is marked extern "C" in the headers. If MS
> doesn't document that, complain to them.

What else internal details they have to document - and why I have to
complain?
Do you document every internal detail of your library functions, not just
what
user needs to know?
And how it is related to this discussion?


>
> > 2. Whether or not I can reliebly pass a pointer to C++ function to the
MSVC
> > library function depends on the function - again I can't find any
> > limitation
> > in the MSVC C/C++ documentation.
>
> The C++ language definition says that the behavior is undefined. If MS
> tells you that they guarantee it will work, fine. Silence isn't enough.
> And, of course, this isn't an MS forum, so MS-specific limitations need
> to be called out.

Microsoft does not tell it me (at least I do not know about that) and I am
not
very much interestrd (though may be curious). Microsoft tells
me how to use "_beginthread" function and I do it according to that.

By the way, did you ever look inside Microsoft (or GNU, or whatever)
sources?
You will see many things that are not just undefined, but plainly wrong
according
to C++ standard - so what?

> >
> > I do not pass pointer to Do_ to my own "extern "C"" function (in wich
case I
> > would agree with you) - I just pass it to the MSVC library function and
> > can/should
> > rely on their documentation.
>
> And what in their documentation tells you what the behavior is when you
> pass a function with C++ linkage to an API function that expects a
> function with C linkage?

When have you found in MS documentation that this API function
(_beginthread)
expects a function with C linkage? Have I missed it?

>
> >
> > (Note - for all C/C++ implementation I used to work with "C" and "C++"
> > linkages
> > for both regular functions and static member functions had only one
> > difference
> > I knew: name mangling. Though it could be differences related to
exceptions
> > and of cause it does not have to be fo every C/C++ implementation)
> >
>
> Nevertheless, the two are different, and some compilers will complain if
> you try to mix them.

That is what I just sayd: "it does not have to be fo every C/C++
implementation".

Pete Becker

unread,
Jun 26, 2003, 5:07:58 PM6/26/03
to

The C++ language definition makes a distinction between C linkage and
C++ linkage. That isn't a distinction that C makes, because it predates
C++. So C documentation typcialy doesn't mention this, because it simply
isn't relevant to C programmers. It matters, though, when you write C++
code. A pointer to a function with C++ linkage isn't compatible with a
pointer to a function with C linkage.

> >
> > > 2. Whether or not I can reliebly pass a pointer to C++ function to the
> MSVC
> > > library function depends on the function - again I can't find any
> > > limitation
> > > in the MSVC C/C++ documentation.
> >
> > The C++ language definition says that the behavior is undefined. If MS
> > tells you that they guarantee it will work, fine. Silence isn't enough.
> > And, of course, this isn't an MS forum, so MS-specific limitations need
> > to be called out.
>
> Microsoft does not tell it me (at least I do not know about that) and I am
> not
> very much interestrd (though may be curious). Microsoft tells
> me how to use "_beginthread" function and I do it according to that.

Where does Microsoft document that the address of a static member
function can be passed to _beginthread?

>
> By the way, did you ever look inside Microsoft (or GNU, or whatever)
> sources?
> You will see many things that are not just undefined, but plainly wrong
> according
> to C++ standard - so what?

The fact that some people write sloppy code doesn't justify advising
people to write sloppy code.

>
> > >
> > > I do not pass pointer to Do_ to my own "extern "C"" function (in wich
> case I
> > > would agree with you) - I just pass it to the MSVC library function and
> > > can/should
> > > rely on their documentation.
> >
> > And what in their documentation tells you what the behavior is when you
> > pass a function with C++ linkage to an API function that expects a
> > function with C linkage?
>
> When have you found in MS documentation that this API function
> (_beginthread)
> expects a function with C linkage? Have I missed it?

I haven't seen it in the MS documentation. As I clearly said above, I
found it in the MS headers.

>
> >
> > >
> > > (Note - for all C/C++ implementation I used to work with "C" and "C++"
> > > linkages
> > > for both regular functions and static member functions had only one
> > > difference
> > > I knew: name mangling. Though it could be differences related to
> exceptions
> > > and of cause it does not have to be fo every C/C++ implementation)
> > >
> >
> > Nevertheless, the two are different, and some compilers will complain if
> > you try to mix them.
>
> That is what I just sayd: "it does not have to be fo every C/C++
> implementation".
>

So, you unconditionally advise people to do this even though you know
that it won't necessarily work?

Michael Furman

unread,
Jun 26, 2003, 6:44:50 PM6/26/03
to
"Pete Becker" <peteb...@acm.org> wrote in message
news:3EFB60AE...@acm.org...

> > > > > Thread::Do_ has C++ linkage; you can't reliably pass a pointer to
it
> > > > > into a C function. For that you need a function with extern "C"
> > linkage:
> > > >
> > > > I believe it is not true:
> > > > 1. I don't see in MSVC documentation any refering to _beginthread as
to
> > > > "C" function.
> > >
> > > Every Win32 API function is marked extern "C" in the headers. If MS
> > > doesn't document that, complain to them.
> >
> > What else internal details they have to document - and why I have to
> > complain?
> > Do you document every internal detail of your library functions, not
just
> > what
> > user needs to know?
> > And how it is related to this discussion?
>
> The C++ language definition makes a distinction between C linkage and
> C++ linkage. That isn't a distinction that C makes, because it predates
> C++. So C documentation typcialy doesn't mention this, because it simply
> isn't relevant to C programmers. It matters, though, when you write C++
> code. A pointer to a function with C++ linkage isn't compatible with a
> pointer to a function with C linkage.

Sorry, you missed. All what you said is perfectly correct, but unrelated.
And you did not answer even single my question.

I use the proprietary MS library. It has common documentation for C and C++
(in some places they explicitly say about some limitation). It has function
"_beginthread" that is described in the documentation w/o mentioning
any specifics regarding C or C++ use.

What you suggest - to look inside the implementation of this function
(part of the implementation that is in ".h" file can't be hidden) and
look is there something wrong inside. You have found "extern "C"" -
and say that documentation is wrong and I should not use it (as it is
documented) and complain to MS! Are you serious?

What you can say - and you will be perfectly correct:
MS library files either wrong are written in non-standard C++.
So what? They are using their own extensions. In this case
extension is trivial (I am guessing!) - they use the fact that
C and C++ linkages identical (Again, I am only guessing! -
I could be wrong here). So what?

I would much more sympathize you if you complain that I use
non-standard C++ in my example - so, even it would be
admissible - this is not C++ group. But you accuse me of
using vendor-specific library function that is internally
implemented using some non-standard C++ thing!

> > >
> > > > 2. Whether or not I can reliably pass a pointer to C++ function to


the
> > MSVC
> > > > library function depends on the function - again I can't find
any
> > > > limitation
> > > > in the MSVC C/C++ documentation.
> > >
> > > The C++ language definition says that the behavior is undefined. If MS
> > > tells you that they guarantee it will work, fine. Silence isn't
enough.
> > > And, of course, this isn't an MS forum, so MS-specific limitations
need
> > > to be called out.
> >
> > Microsoft does not tell it me (at least I do not know about that) and I
am
> > not
> > very much interestrd (though may be curious). Microsoft tells
> > me how to use "_beginthread" function and I do it according to that.
>
> Where does Microsoft document that the address of a static member
> function can be passed to _beginthread?

Here you have caught me better - now you are not talking about "extern "C""
but find another thing. Microsoft does not document it - as I believe it is
documented in the C++ standard:

//== Start of quote

[expr.call] 5.2.2 Function call

1 There are two kinds of function call: ordinary function call and member
function57) (9.3) call. A function call is a postfix expression followed by
parentheses
containing a possibly empty, comma separated list of expressions which
constitute
the arguments to the function. For an ordinary function call, the postfix
expression shall be either an lvalue that refers to a function (in which
case the function-to-pointer standard conversion (4.3) is suppressed on the
postfix
expression), or it shall have pointer to function type. Calling a
function through an expression whose function type has a language linkage
that is different from the
language linkage of the function type of the called function’s definition is
undefined (7.5).
__________________

56) This is true even if the subscript operator is used in the following
common idiom: &x[0].

57) A static member function (9.4) is an ordinary function.

==== End of quote

I guess we become offtopic in the threads group - if you don't agree with
this
one - let's move to one of C++ group.


>
> >
> > By the way, did you ever look inside Microsoft (or GNU, or whatever)
> > sources?
> > You will see many things that are not just undefined, but plainly wrong
> > according
> > to C++ standard - so what?
>
> The fact that some people write sloppy code doesn't justify advising
> people to write sloppy code.

Do you believe that any non-standard-C++ code is sloppy? If so,
you have to believe that any other-language code is sloppy?
Are you serious?

>
> >
> > > >
> > > > I do not pass pointer to Do_ to my own "extern "C"" function (in
wich
> > case I
> > > > would agree with you) - I just pass it to the MSVC library function
and
> > > > can/should
> > > > rely on their documentation.
> > >
> > > And what in their documentation tells you what the behavior is when
you
> > > pass a function with C++ linkage to an API function that expects a
> > > function with C linkage?
> >
> > When have you found in MS documentation that this API function
> > (_beginthread)
> > expects a function with C linkage? Have I missed it?
>
> I haven't seen it in the MS documentation. As I clearly said above, I
> found it in the MS headers.

You do'nt do it every time - post withou evel looking what is it about.
I read a lot of good posts of you in C++ groups - what happened now?


>
> >
> > >
> > > >
> > > > (Note - for all C/C++ implementation I used to work with "C" and
"C++"
> > > > linkages
> > > > for both regular functions and static member functions had only one
> > > > difference
> > > > I knew: name mangling. Though it could be differences related to
> > exceptions
> > > > and of cause it does not have to be fo every C/C++ implementation)
> > > >
> > >
> > > Nevertheless, the two are different, and some compilers will complain
if
> > > you try to mix them.
> >
> > That is what I just sayd: "it does not have to be fo every C/C++
> > implementation".
> >
>
> So, you unconditionally advise people to do this even though you know
> that it won't necessarily work?

Where did I advise whhat?
May be I am crazy and "_beginthread" is a standard C function? (...
searching
standards and some other texts ... ). No, I am not! :-) - it is just
Microsoft
proprietary library function.
And BTW I am not advizing people using MS functions - IMO there are lots
of problems with MS software.
But there is no problem with this function in this case of use (I know
about) - the code
(I took fragments from) is written according to the documentation int it
works.

Is it enough?
If you think it is not, please either:
- pointing at my errors give some proof and/or pointing at some texts (in
this case it could be
C++ standard and/or MS documentation). I would appreciate it.
- answer my questions.

Regards,
Michael Furman

Pete Becker

unread,
Jun 26, 2003, 7:31:38 PM6/26/03
to
Michael Furman wrote:
>
> I use the proprietary MS library.

You didn't mention that when you said:

It is not a problem. You can use static method as thread
function and path pointer to the class insttance as a
parameter. For convinience I usually define another
non-static function and call it from the static one.

> It has common documentation for C and C++


> (in some places they explicitly say about some limitation). It has function
> "_beginthread" that is described in the documentation w/o mentioning
> any specifics regarding C or C++ use.

Yup: it doesn't tell you whether you can call it with a function that
has C++ linkage.

>
> What you suggest - to look inside the implementation of this function
> (part of the implementation that is in ".h" file can't be hidden) and
> look is there something wrong inside. You have found "extern "C"" -
> and say that documentation is wrong and I should not use it (as it is
> documented)

Where in the documentation does it tell you that you can pass a static
member function to _beginthread?

> and complain to MS! Are you serious?

Yup. If their documentation doesn't give you the information that you
ought to have to use their library correctly you should complain.

>
> What you can say - and you will be perfectly correct:
> MS library files either wrong are written in non-standard C++.
> So what? They are using their own extensions. In this case
> extension is trivial (I am guessing!) - they use the fact that
> C and C++ linkages identical (Again, I am only guessing! -
> I could be wrong here). So what?

You say twice that you're guessing and you say "I could be wrong," and
you don't see any problem? That's the problem.

>
> I would much more sympathize you if you complain that I use
> non-standard C++ in my example - so, even it would be
> admissible - this is not C++ group. But you accuse me of
> using vendor-specific library function that is internally
> implemented using some non-standard C++ thing!

I didn't accuse you of anything. I pointed out that the code you posted
wouldn't necessarily work. You now agree that that's true.

>
> > > >
> > > > > 2. Whether or not I can reliably pass a pointer to C++ function to
> the
> > > MSVC
> > > > > library function depends on the function - again I can't find
> any
> > > > > limitation
> > > > > in the MSVC C/C++ documentation.
> > > >
> > > > The C++ language definition says that the behavior is undefined. If MS
> > > > tells you that they guarantee it will work, fine. Silence isn't
> enough.
> > > > And, of course, this isn't an MS forum, so MS-specific limitations
> need
> > > > to be called out.
> > >
> > > Microsoft does not tell it me (at least I do not know about that) and I
> am
> > > not
> > > very much interestrd (though may be curious). Microsoft tells
> > > me how to use "_beginthread" function and I do it according to that.
> >
> > Where does Microsoft document that the address of a static member
> > function can be passed to _beginthread?
>
> Here you have caught me better - now you are not talking about "extern "C""
> but find another thing. Microsoft does not document it - as I believe it is
> documented in the C++ standard:

No, the C++ standard does not document whether you can pass a static
member function to _beginthread. As you pointed out, _beginthread is
proprietary. Its properties are not described by the C++ standard. But
you did quote an important part of the standard:

> Calling a
> function through an expression whose function type has a language linkage
> that is different from the
> language linkage of the function type of the called function’s definition is
> undefined (7.5).

Static member functions have C++ linkage. _beginthread takes a pointer
to a function with C linkage. So the C++ standard does not require that
this work.

> > > > >
> > > > > (Note - for all C/C++ implementation I used to work with "C" and
> "C++"
> > > > > linkages
> > > > > for both regular functions and static member functions had only one
> > > > > difference
> > > > > I knew: name mangling. Though it could be differences related to
> > > exceptions
> > > > > and of cause it does not have to be fo every C/C++ implementation)
> > > > >
> > > >
> > > > Nevertheless, the two are different, and some compilers will complain
> if
> > > > you try to mix them.
> > >
> > > That is what I just sayd: "it does not have to be fo every C/C++
> > > implementation".
> > >
> >
> > So, you unconditionally advise people to do this even though you know
> > that it won't necessarily work?
>
> Where did I advise whhat?

In your original posting to this thread you said:

It is not a problem. You can use static method as thread
function and path pointer to the class insttance as a
parameter. For convinience I usually define another
non-static function and call it from the static one.

> May be I am crazy and "_beginthread" is a standard C function? (...


> searching
> standards and some other texts ... ). No, I am not! :-) - it is just
> Microsoft
> proprietary library function.
> And BTW I am not advizing people using MS functions - IMO there are lots
> of problems with MS software.
> But there is no problem with this function in this case of use (I know
> about) - the code
> (I took fragments from) is written according to the documentation int it
> works.
>
> Is it enough?
> If you think it is not, please either:
> - pointing at my errors give some proof and/or pointing at some texts (in
> this case it could be
> C++ standard and/or MS documentation). I would appreciate it.

You already quoted the part of the C++ standard that says this isn't
required to work, and you haven't cited any MS documentation that says
it will work. It is not sound engineering to assert that "it is not a
problem."

Michael Furman

unread,
Jun 26, 2003, 8:45:12 PM6/26/03
to
I started to be tired.

"Pete Becker" <peteb...@acm.org> wrote in message

news:3EFB825A...@acm.org...


> Michael Furman wrote:
> >
> > I use the proprietary MS library.
>
> You didn't mention that when you said:

> [...]

I did not have to: it was in the question:

"Robert Schneider" <rschn...@testo.de> wrote in message
news:9a0110ad.0306...@posting.google.com...
> What do you think or suggest?
>
> I use VC++ (and COM, so I cannot avoid object oriented programming).

> [....]

> > It has common documentation for C and C++
> > (in some places they explicitly say about some limitation). It has
function
> > "_beginthread" that is described in the documentation w/o mentioning
> > any specifics regarding C or C++ use.
>
> Yup: it doesn't tell you whether you can call it with a function that
> has C++ linkage.

As well as it does not tell whether you can call it with a function that
has C linkage. (in some cases it tells though).

> > What you suggest - to look inside the implementation of this function
> > (part of the implementation that is in ".h" file can't be hidden) and
> > look is there something wrong inside. You have found "extern "C"" -
> > and say that documentation is wrong and I should not use it (as it is
> > documented)
>
> Where in the documentation does it tell you that you can pass a static
> member function to _beginthread?

I suggest you read the whole post before answering.

>
> > and complain to MS! Are you serious?
>
> Yup. If their documentation doesn't give you the information that you
> ought to have to use their library correctly you should complain.

Why you want me to know internal implementation details of their
library? (actually I am curious and know much more that I pretend,
but it is unrelated)

>
> >
> > What you can say - and you will be perfectly correct:
> > MS library files either wrong are written in non-standard C++.
> > So what? They are using their own extensions. In this case
> > extension is trivial (I am guessing!) - they use the fact that
> > C and C++ linkages identical (Again, I am only guessing! -
> > I could be wrong here). So what?
>
> You say twice that you're guessing and you say "I could be wrong," and
> you don't see any problem? That's the problem.

Problem with what? I was talking about what you could say but did not!
How it related to anything we discussing?

>
> >
> > I would much more sympathize you if you complain that I use
> > non-standard C++ in my example - so, even it would be
> > admissible - this is not C++ group. But you accuse me of
> > using vendor-specific library function that is internally
> > implemented using some non-standard C++ thing!
>
> I didn't accuse you of anything. I pointed out that the code you posted
> wouldn't necessarily work. You now agree that that's true.

Sure it would not work on any other platform then MSVC: it is using
MS proprietary library.
First time in this discussion you said something that is absolutely
correct and have some relation to the topic!

Are you sure you understand what you are saying? "_beginthread" is not
defined by C++ standard! What it says that pointers to static member
functions are pointers to ordinary functions.

> you did quote an important part of the standard:
>
> > Calling a
> > function through an expression whose function type has a language
linkage
> > that is different from the
> > language linkage of the function type of the called function's
definition is
> > undefined (7.5).
>
> Static member functions have C++ linkage. _beginthread takes a pointer
> to a function with C linkage. So the C++ standard does not require that
> this work.

Sure it does not require function "_beginthread" to work. Did I say that it
does?
What is requires this Microsoft function to work is Microsoft documentation.

>
> > > > > >
> > > > > > (Note - for all C/C++ implementation I used to work with "C" and
> > "C++"
> > > > > > linkages
> > > > > > for both regular functions and static member functions had only
one
> > > > > > difference
> > > > > > I knew: name mangling. Though it could be differences related to
> > > > exceptions
> > > > > > and of cause it does not have to be fo every C/C++
implementation)
> > > > > >
> > > > >
> > > > > Nevertheless, the two are different, and some compilers will
complain
> > if
> > > > > you try to mix them.
> > > >
> > > > That is what I just sayd: "it does not have to be fo every C/C++
> > > > implementation".
> > > >
> > >
> > > So, you unconditionally advise people to do this even though you know
> > > that it won't necessarily work?
> >
> > Where did I advise whhat?
>
> In your original posting to this thread you said:
>
> It is not a problem. You can use static method as thread
> function and path pointer to the class insttance as a
> parameter. For convinience I usually define another
> non-static function and call it from the static one.

Why do you believe that it would is not necessarily work?
(besides bugs in MS software)?

>
> > May be I am crazy and "_beginthread" is a standard C function? (...
> > searching
> > standards and some other texts ... ). No, I am not! :-) - it is just
> > Microsoft
> > proprietary library function.
> > And BTW I am not advizing people using MS functions - IMO there are lots
> > of problems with MS software.
> > But there is no problem with this function in this case of use (I know
> > about) - the code
> > (I took fragments from) is written according to the documentation int it
> > works.
> >
> > Is it enough?
> > If you think it is not, please either:
> > - pointing at my errors give some proof and/or pointing at some texts
(in
> > this case it could be
> > C++ standard and/or MS documentation). I would appreciate it.
>
> You already quoted the part of the C++ standard that says this isn't
> required to work, and you haven't cited any MS documentation that says
> it will work. It is not sound engineering to assert that "it is not a
> problem."

Again... C++ standard can't require Microsoft function to work, like
it does not require my car to run.
About MS documentation - it is long. If you dont believe me, just look
at help "_beginthread". And look at the title of the document it found:
"Visual C++ programmers guide".

You can also look at the example how to use it in the article Q132078.


Some summary:

1. When using proprietary software we have to use its documentation
rather then look at the internal implementation.

2. You looked inside the implementation of "_beginthread"
function and found that it is not very elegantly uses some
non-standard extensions - I agree. Such code is not portable -
I also agree and would not recommend Microsoft to compile
it under conforming C++ implementation.

3. You probably did not read initial Robert Schneider's question
where he said that it is about Microsft thread functions and did not
check that function "_beginthread" are exclusively MS. Now you know.

4. It is not sound engineering to advise peoples read implementation
code of library functions and deduct how they can be used rather
then read documentation with descriptions how they intended to
be used. (actually I believe that it is not just "not sound
engineering"
but plainly wrong and very dangerous).

I believe this is an end of this thread, is not it?


Michael Furman

David Schwartz

unread,
Jun 26, 2003, 8:57:22 PM6/26/03
to

"Michael Furman" <Michae...@Yahoo.com> wrote in message
news:bdg42q$s8b5b$1...@ID-122417.news.dfncis.de...

> 4. It is not sound engineering to advise peoples read implementation
> code of library functions and deduct how they can be used rather
> then read documentation with descriptions how they intended to
> be used. (actually I believe that it is not just "not sound
> engineering"
> but plainly wrong and very dangerous).

But that's not what he did. He read the implementation and deduced from
that how it could *not* safely be used. This is both sound engineering and
very safe. (In this case, I think his argument is erroneous, but so is
yours.)

DS


Michael Furman

unread,
Jun 26, 2003, 9:21:21 PM6/26/03
to

"David Schwartz" <dav...@webmaster.com> wrote in message
news:bdg4pi$lc0$1...@nntp.webmaster.com...

I could not agree with you here. If so, he should have posted it in some
MS newsgroup with subject "I think it is not safe to use _beginthread
in Visual C++ envirenment" - and I wouls appreciate it even in case
he is wrong.

It is wrong to promote using "inside" information rather then documentation
in case of just using some function. Especially for a person whose name is
known. Regardless of whether it erroneous or not!

It was a simple question how to use it - and I just answered it. I could
have
made some mistakes in my answer, but now, after this discussion
it seems that I have not.

Regards,
Micahel Furman

>
> DS
>
>


Alexander Terekhov

unread,
Jun 27, 2003, 6:00:11 AM6/27/03
to

Michael Furman wrote:

[... _beginthread ...]

> It was a simple question how to use it - and I just answered it. I could
> have made some mistakes in my answer, but now, after this discussion
> it seems that I have not.

http://groups.google.com/groups?selm=3CC57820.613866FE%40web.de
http://groups.google.com/groups?selm=3ECB8F71.689E551C%40web.de
http://groups.google.com/groups?selm=3ECE1254.20134D8B%40web.de

regards,
alexander.

Michael Furman

unread,
Jun 27, 2003, 1:40:11 PM6/27/03
to

"Alexander Terekhov" <tere...@web.de> wrote in message
news:3EFC15AB...@web.de...

Did you want to say something and just forgot?
Regards,
Michael
>
> regards,
> alexander.


Steve Watt

unread,
Jun 27, 2003, 3:28:34 PM6/27/03
to
In article <bdhvht$t7hns$1...@ID-122417.news.dfncis.de>,

Michael Furman <Michae...@Yahoo.com> wrote:
>
>"Alexander Terekhov" <tere...@web.de> wrote in message
>news:3EFC15AB...@web.de...
>>
>> Michael Furman wrote:
>>
>> [... _beginthread ...]
>>
>> > It was a simple question how to use it - and I just answered it. I could
>> > have made some mistakes in my answer, but now, after this discussion
>> > it seems that I have not.
>>
>> http://groups.google.com/groups?selm=3CC57820.613866FE%40web.de

(To Alexander: You're one of the few people I read who would post
such a pointer. I hereby accuse you of mild silliness. :)

Alexander does that occasionally. There's something in the referenced
articles that he thinks you should read. I happen to think so as
well, but I'll let you go read them.

--
Steve Watt KD6GGD PP-ASEL-IA ICBM: 121W 56' 57.8" / 37N 20' 14.9"
Internet: steve @ Watt.COM Whois: SW32
Free time? There's no such thing. It just comes in varying prices...

Michael Furman

unread,
Jun 27, 2003, 3:42:53 PM6/27/03
to

"Steve Watt" <st...@nospam.Watt.COM> wrote in message
news:HH5nF...@Watt.COM...

> In article <bdhvht$t7hns$1...@ID-122417.news.dfncis.de>,
> Michael Furman <Michae...@Yahoo.com> wrote:
> >
> >"Alexander Terekhov" <tere...@web.de> wrote in message
> >news:3EFC15AB...@web.de...
> >>
> >> Michael Furman wrote:
> >>
> >> [... _beginthread ...]
> >>
> >> > It was a simple question how to use it - and I just answered it. I
could
> >> > have made some mistakes in my answer, but now, after this discussion
> >> > it seems that I have not.
> >>
> >> http://groups.google.com/groups?selm=3CC57820.613866FE%40web.de
>
> (To Alexander: You're one of the few people I read who would post
> such a pointer. I hereby accuse you of mild silliness. :)
>
> >> http://groups.google.com/groups?selm=3ECB8F71.689E551C%40web.de
> >> http://groups.google.com/groups?selm=3ECE1254.20134D8B%40web.de
> >
> >Did you want to say something and just forgot?
>
> Alexander does that occasionally. There's something in the referenced
> articles that he thinks you should read. I happen to think so as
> well, but I'll let you go read them.

I've done it before posting a question.

Michael.


Alexander Terekhov

unread,
Jun 27, 2003, 5:46:52 PM6/27/03
to

Yes. Microsoft must die.

http://groups.google.com/groups?selm=3EF0D8E3.ECFE0E25%40web.de
(Subject: Re: MUTEX)

regards,
alexander.

Yuval Hofshy

unread,
Jun 29, 2003, 4:45:23 AM6/29/03
to
rschn...@testo.de (Robert Schneider) wrote in message news:<9a0110ad.0306...@posting.google.com>...

Hi,

If polymorphism behavior is not required, there is no need for
wrapping thread's entry point in a base class, and deriving concrete
threads classes from that class.
This approach is good for programming languages like Java and C# where
the common way to reuse code is via sub classing.
C++ supports generic programming via templates as well. This can be
used to create reusable wrapper for the underlying OS C threading API.
Here is a SIMPLE example:
Note that this example hides all the C stuff, uses objects as entry
points of threads, but does not introduce run time overhead such as
virtual tables.

// **************************************************
#include <memory>

#ifdef USE_WIN32_THREADS
#include <windows.h>
#elif defined (USE_POSIX_THREADS)
#include <pthread.h>
#else
#error blablabla
#endif


template <class implementation_t, bool params_owner = true>
class TSimpleThread
{
private:
typedef typename implementation_t::message_t message_t;

private:
TSimpleThread();
~TSimpleThread();

public:
static bool spawn(message_t *pMessage);

private:
#if defined (USE_POSIX_THREADS)
static void *entrypoint(void *pParams);
#elif defined (USE_WIN32_THREADS)
static DWORD WINAPI entrypoint(LPVOID pParams);
#else
#error blablabla
#endif
};

template <class implementation_t, bool params_owner>
bool TSimpleThread<implementation_t, params_owner>::spawn(message_t
*pMessage)
{
bool fResult = false;
#if defined (USE_WIN32_THREADS)
DWORD id;
fResult = CreateThread(NULL, 0, entrypoint, pMessage, 0, &id) !=
NULL;
#elif defined (USE_POSIX_THREADS)
pthread_t id;
fResult = pthread_create(&id, NULL, entrypoint, pMessage) == 0;
#else
#error blablabla
#endif
return fResult;
} // spawn


template <class implementation_t, bool params_owner>
#if defined (USE_POSIX_THREADS)
void *TSimpleThread<implementation_t, params_owner>::entrypoint(void
*pParams)
#elif defined (USE_WIN32_THREADS)
DWORD WINAPI TSimpleThread<implementation_t,
params_owner>::entrypoint(LPVOID pParams)
#else
#error blablabla
#endif
{
if (pParams)
{
std::auto_ptr<message_t>
pMessage(reinterpret_cast<message_t*>(pParams));
implementation_t impl;
impl(*pMessage);
if (!params_owner)
{
pMessage.release();
}
}
return 0;
} // entrypoint

// **************************************************

Usage example:


class my_message;

class A
{
public:
typedef my_message message_t;

public:
A() {};
~A() {};
....
void operator()(const my_message &message)
{
// the code to be executed by the new thread
}
};

// create a new thread, which executes A's code
my_message m;
TSimpleThread<A, false>::spawn(&m);

// create a new thread, which executes A's code, and OWNS the message:
my_message *pM = new my_message();
if (pM)
{
TSimpleThread<A, true>::spawn(pM);
}
else
{
...
}

// **************************************************


Anyway, if possible consider using libraries which wraps all the
threading related APIs, such as threads creation and synchronization,
with a nice OO design.
Check out:
Boost.Threads: http://www.boost.org/libs/thread/doc/index.html
ACE: http://www.cs.wustl.edu/~schmidt/ACE.html


Hope that helps,
Yuval

Balog Pal

unread,
Jul 11, 2003, 5:01:26 PM7/11/03
to
"Michael Furman" <Michae...@Yahoo.com> wrote in message
news:bdflpj$sd1ic$1...@ID-122417.news.dfncis.de...

> "Pete Becker" <peteb...@acm.org> wrote in message
> news:3EFB52F4...@acm.org...

> By the way, did you ever look inside Microsoft (or GNU, or whatever)
> sources?

ROTFL. Look around, man, Pete actually WROTE some of those sources you
got with your MSVC. You'd better pay attention to what he says.

Even though I don't agree with his _main_ reasoning here.

Function _beginthread has a page of documentation. It describes what kind of
function it expects. As one pointed by a void( __cdecl *start_address )(
void * ). That's it, that's all.
No requirement on its having either C or C++ linkage is specified, and to me
that IMPLIES it will deal with either.
It is true, that mixing is undefined behavior in general, but implementation
may define it, like treating them as equals. And my observation from
experience is they are indeed the same.
Even if that is not specified (possibly it is, just where to find it :)
quite many functions take pointers to functions, and the difference is
nowhere mentioned. An I see no reason to claim 'documentation is wrong' on
this basis -- documentation is consistent with beavior and what proof we
have it means not what it intended? Why should we thing that missing
restrictions meand NOT that those restrictions just not exist?

[These are questions to Pete ;]

What's indeed important, the calling convention. But that is included in the
type, unless you use a c-style cast the compiler will catch you attempting
to pass a __stdcall function where a __cdecl one is expected. AFAIK extern
"C" only changes the name mangling, nothing else, and that is irrelevant
when all you have is a pointer to function.

Paul


Michael Furman

unread,
Jul 11, 2003, 4:20:15 PM7/11/03
to

"Balog Pal" <pa...@lib.hu> wrote in message
news:3f0f...@andromeda.datanet.hu...

> "Michael Furman" <Michae...@Yahoo.com> wrote in message
> news:bdflpj$sd1ic$1...@ID-122417.news.dfncis.de...
>
> > "Pete Becker" <peteb...@acm.org> wrote in message
> > news:3EFB52F4...@acm.org...
>
> > By the way, did you ever look inside Microsoft (or GNU, or whatever)
> > sources?
>
> ROTFL. Look around, man, Pete actually WROTE some of those sources you
> got with your MSVC. You'd better pay attention to what he says.
>
> Even though I don't agree with his _main_ reasoning here.

Is it a joke? Or you did not sleep well, did not get enough cofee etc.?
What did you want to say? Is it that Pete is wrong?, but I must
shutup despite that?
BTW, do you know how mach of such code I WROTE? I would say "You'd better
pay attention
to what I say", but you actually do.

Michael Furman


Michael Furman

unread,
Jul 11, 2003, 4:27:09 PM7/11/03
to

"Balog Pal" <pa...@lib.hu> wrote in message
news:3f0f...@andromeda.datanet.hu...
> [...]

> [These are questions to Pete ;]
>
> What's indeed important, the calling convention. But that is included in
the
> type, unless you use a c-style cast the compiler will catch you attempting
> to pass a __stdcall function where a __cdecl one is expected. AFAIK extern
> "C" only changes the name mangling, nothing else, and that is irrelevant
> when all you have is a pointer to function.

You are wrong here -"extern "C"" can change anything and even in case of
MSVC
it is not garanteed that it does not (If I am wrong, please give a quote
from MS
documentation).

Michael Furman


Balog Pal

unread,
Jul 11, 2003, 6:15:41 PM7/11/03
to
"Michael Furman" <Michae...@Yahoo.com> wrote in message
news:ben66b$777c6$1...@ID-122417.news.uni-berlin.de...

> > > By the way, did you ever look inside Microsoft (or GNU, or whatever)
> > > sources?
> >
> > ROTFL. Look around, man, Pete actually WROTE some of those sources
you
> > got with your MSVC. You'd better pay attention to what he says.
> >
> > Even though I don't agree with his _main_ reasoning here.
>
> Is it a joke? Or you did not sleep well, did not get enough cofee etc.?
> What did you want to say? Is it that Pete is wrong?, but I must
> shutup despite that?

Look you wrote half book'a woth of text, and he was right in a plenty of
points. OTOH I tend to listen to people even if they happen to talk about
stuff not really related to some of my problem.

But what I was commenting is different. You asked someone if he ever looked
at some set of sources -- when he very likely actually worked on them. It's
just like asking Andrew Koenig if he ever came to read the C++ standard.

> BTW, do you know how mach of such code I WROTE?

No, and I dont; care. i didn;t ask you whether you read any of those sources
you wrote did I? ;-))

> I would say "You'd better
> pay attention
> to what I say", but you actually do.

Yes I pay attention to people, and try to learn something from every piece
of information.

From the other post:


>>
You are wrong here -"extern "C"" can change anything and even in case of
MSVC
it is not garanteed that it does not (If I am wrong, please give a quote
from MS
documentation).
<<

And that really confuses me.

Let's have

extern "C" void __cdecl cfoo(void*);
and
struct bar {
static void __cdecl foo(void*);
};
with identical implementation. Will they produce the same machine code or
not (using MSVC)?

If not, why will they work correctly if their address is passed to a
function, like beginthread?
Or if you say only one is guaranteed to work, where the documentation states
which is that one?

Paul


Michael Furman

unread,
Jul 11, 2003, 11:17:38 PM7/11/03
to

"Balog Pal" <pa...@lib.hu> wrote in message
news:3f0f...@andromeda.datanet.hu...
> "Michael Furman" <Michae...@Yahoo.com> wrote in message
> news:ben66b$777c6$1...@ID-122417.news.uni-berlin.de...
>
> > > > By the way, did you ever look inside Microsoft (or GNU, or whatever)
> > > > sources?
> > >
> > > ROTFL. Look around, man, Pete actually WROTE some of those sources
> you
> > > got with your MSVC. You'd better pay attention to what he says.
> > >
> > > Even though I don't agree with his _main_ reasoning here.
> >
> > Is it a joke? Or you did not sleep well, did not get enough cofee etc.?
> > What did you want to say? Is it that Pete is wrong?, but I must
> > shutup despite that?
>
> Look you wrote half book'a woth of text, and he was right in a plenty of
> points. OTOH I tend to listen to people even if they happen to talk about
> stuff not really related to some of my problem.

This absolutely fullish. Arguing with Pete was related to something -
everyone
make mistakes. Yes, he was righ in plenty of point (not in that
discussion) - so what?


>
> But what I was commenting is different. You asked someone if he ever
looked
> at some set of sources -- when he very likely actually worked on them.
It's
> just like asking Andrew Koenig if he ever came to read the C++ standard.

I would not discuss with you (either in ppublic forum or privately) Petes
credentials -
I believe it is upolite and even rude.


>
> > BTW, do you know how mach of such code I WROTE?
>
> No, and I dont; care. i didn;t ask you whether you read any of those
sources
> you wrote did I? ;-))

I did not ask you either.

>
> > I would say "You'd better
> > pay attention
> > to what I say", but you actually do.
>
> Yes I pay attention to people, and try to learn something from every piece
> of information.

But as I see without any success.

>
> From the other post:
> >>
> You are wrong here -"extern "C"" can change anything and even in case of
> MSVC
> it is not garanteed that it does not (If I am wrong, please give a quote
> from MS
> documentation).
> <<
>
> And that really confuses me.
>
> Let's have
>
> extern "C" void __cdecl cfoo(void*);
> and
> struct bar {
> static void __cdecl foo(void*);
> };
> with identical implementation. Will they produce the same machine code
or
> not (using MSVC)?
>
> If not, why will they work correctly if their address is passed to a
> function, like beginthread?
> Or if you say only one is guaranteed to work, where the documentation
states
> which is that one?

I never said anything like that. What I said that this equality is not
garanteed by Standard
and even not garanteed by MS. So, if we forget the fact that using
_beginthread is allowed
by MS documentation directly from C++ and look inside the implementation -
what Pete
said would be absolutely true. Though in my strong opinion, looking in the
implementation
details rather than reading documentation, if we are talking about using
something is a very
bad practice.

Michael Furman

0 new messages