Tuesday, May 2, 2017

Digest for comp.lang.c++@googlegroups.com - 14 updates in 7 topics

rami17 <rami17@rami17.net>: May 02 10:02PM -0400

Hello....
 
 
My Object oriented Stackful coroutines library for Delphi and FreePascal
version 2.0 is here..
 
I have completly rewritten the 64 bit and 32 bit library for FPC and
the 32 bit library for Delphi XE, i have enhanced it and you have to
take a look at it , it is now really good and really fast and more stable.
 
Now it is working with Windows and Linux and MacOSX on (x86), i have
just booted on Linux and compiled it with FreePascal on Linux and it is
working correctly and it is really good.
 
Please take a look at the source code to learn more how to use it.
 
You can download the new version 2.0 from:
 
https://sites.google.com/site/aminer68/object-oriented-stackful-coroutines-library-for-delphi-and-freepascal
 
 
.
Thank you,
Amine Moulay Ramdane.
rami17 <rami17@rami17.net>: May 02 10:27PM -0400

Hello,
 
 
Sorry it is a mistake, i have posted here, but it is a Delphi and
FreePascal project.
 
 
Thank you,
Amine Moulay Ramdane.
Jorgen Grahn <grahn+nntp@snipabacken.se>: May 02 06:39PM

On Fri, 2017-03-31, woodbrian77@gmail.com wrote:
...
 
> make all example
 
> I'm not sure if it would be better to include the example
> target in all or leave it separate.
 
It's a matter of taste, but I like 'all' to mean "build everything
that can conceivably be built" so that's a vote for a line which says:
 
all: example
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Jorgen Grahn <grahn+nntp@snipabacken.se>: May 02 06:52PM

> that could be improved on:
 
> https://bitbucket.org/webenezer/onwards/src/7a925499bdaa2ce53df5401f255b2db9d6100bf0/makefile.windows?at=master&fileviewer=file-view-default
 
> Let me know if that link doesn't work -- I'll post the file.
 
I don't know Windows make (if that's what you're using), but this part:
 
.c.obj:
$(CC) $(CFLAGS) -c $*.c -o $*.obj
 
quicklz.obj: quicklz.h
$(CC) $(CFLAGS) -c quicklz.c
 
marshalling_integer.obj: marshalling_integer.hh
$(CC) $(CFLAGS) -c marshalling_integer.cc
 
- Are the dependencies on header files really that simple, just two of
them? If not, you risk broken builds, if you change a header and
expect an incremental build to work correctly.
 
- The .c.obj line tells what command produces foo.obj from foo.c, but
then you repeat that for quicklz.obj and marshalling_integer.obj. At
least with Gnu Make you can simplify that to:
 
.c.obj:
$(CC) $(CFLAGS) -c $*.c -o $*.obj
 
quicklz.obj: quicklz.h
marshalling_integer.obj: marshalling_integer.hh
 
> One of the rules there uses /link, but two of them don't.
> It seems to work either way.
 
That's
 
tiers\genz.exe: tiers\genz.cc .\libhome.lib
del tiers\string_join.hh tiers\udp_stuff.hh
$(CC) -Fe:$@ $(CFLAGS) -I. tiers\genz.cc /link ...
 
And that's because you both compile tiers\genz.cc and link, producing
the exe file.
 
I think I'd split that into two steps, and explicitly generate
tiers\genz.obj as a first pure compilation step.
 
[snip]
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
fl <rxjwg98@gmail.com>: May 02 02:23AM -0700

Hi,
 
I read "C++ Primer" of Stanley B. Lippman etc. In Chapter 13, it talks about
pointer copy. I looks understand the pointer dangling problem related, but
I don't understand his explanation:
 
"because the value of a pointer
is distinct from the value of the object to which it points."
 
I run the below code snippet on Windows, MSVC.
ptr1 content: {ptr=0x00affa98(0), val=42}
ptr2 content: {ptr=0x00affa98(0), val=42}
 
This simple plain design does have problem, but it doesn't show the problem
only after the copy execution.
 
Could you tell me what the authors say?
"because the value of a pointer
is distinct from the value of the object to which it points."
 
 
Thanks,
 
\\\\\\\\\\\\\\\\\\\\\
 
// class that has a pointer member that behaves like a plain pointer
class HasPtr {
public:
friend ostream& operator<<(ostream&, const HasPtr&);
// copy of the values we're given
HasPtr(int *p, int i): ptr(p), val(i) { }
 
// const members to return the value of the indicated data member
int *get_ptr() const { return ptr; }
int get_int() const { return val; }
 
// nonconst members to change the indicated data member
void set_ptr(int *p) { ptr = p; }
void set_int(int i) { val = i; }
 
// return or change the value pointed to, so ok for const objects
int get_ptr_val() const { return *ptr; }
void set_ptr_val(int val) const { *ptr = val; }
 
private:
int *ptr;
int val;
};
 
/////////////
 
int obj = 0;
 
HasPtr ptr1(&obj, 42); // int* member points to obj, val is 42
HasPtr ptr2(ptr1); // int* member points to obj, val is 42
--------------
 
After the copy, the pointers in ptr1 and ptr2 both address the same object
and the int values in each object are the same. However, the behavior of
these two members appears quite different, because the value of a pointer
is distinct from the value of the object to which it points. After the
copy, the int values are distinct and independent, whereas the pointers are
intertwined.
Paavo Helde <myfirstname@osa.pri.ee>: May 02 12:44PM +0300

On 2.05.2017 12:23, fl wrote:
 
> int obj = 0;
 
> HasPtr ptr1(&obj, 42); // int* member points to obj, val is 42
> HasPtr ptr2(ptr1); // int* member points to obj, val is 42
 
The only problem I see is that both pointers inside objects do not point
to their respective inner member 'val', but point to some outside object
'obj' instead. 'ptr' and 'val' have been put inside the same class, but
they appear to be not connected in any way.
 
As written, there is no dangling pointer yet, but there easily could be
if 'obj' goes out of scope before 'ptr1' or 'ptr2'.
 
Anyway, I guess you are supposed to change the values of obj and val
(via setint()) and observe what numbers are returned by get_int() and
get_ptr_val().
Juha Nieminen <nospam@thanks.invalid>: May 02 01:36PM

> "because the value of a pointer
> is distinct from the value of the object to which it points."
 
I suppose that what the author is trying to say is that when you assign
a pointer to another, they will both point to the same object, rather
than the object itself being copied as well.
 
This raises a problem of ownership, and dangling pointers.
 
The most common problematic scenario is if you allocate something
dynamically (with 'new') and then have two pointers pointing to it.
Since C++ doesn't natively offer any automation on how to manage
the lifetime of that dynamically allocated object, you need to either
be extremely careful with how you handle those pointers, or use
exclusively something like std::shared_ptr to handle it. (In general
it's advisable to avoid this situation altogether, if you can.)
 
But that's only one scenario that causes a problem. You don't even
need dynamic allocation to encounter problems. Suppose you have
something like this:
 
class C
{
int table[10];
int* tablePtr;
 
public:
C(): tablePtr(&table[0]) {}
};
 
That 'tablePtr' is supposed to point to an element of 'table'.
But consider what happens if you do this:
 
C obj1;
C obj2 = obj1;
 
Where do you think the tablePtr of obj2 is pointing to?
 
This becomes especially dangerous if you do seemingly innocuous
things like:
 
C foo() { return C(); }
"Chris M. Thomasson" <invalid@invalid.invalid>: May 01 06:35PM -0700

On 4/26/2017 10:51 PM, Ian Collins wrote:
> the "bus". Worked well with a couple of modules, flat lined my new
> shiny Pentium era build machine with 128...
 
> It would probably work OK on current 32 core/64 thread machines :)
 
I would still feel sorry for that single mutex. ;^)
Bonita Montero <Bonita.Montero@gmail.com>: May 02 02:09PM +0200

> Its a race-condition. ...
 
Theoretically. Practically, even if I repeatedly read the last block
in every iteration, the code never fails - although on my SSD it is
about three to four seconds until the file is successfully enlarged.
So it seems like I assumed: the enlagement becomes visible immediately
after WriteFile.
 
But there's theroetically another bug: the ReadFile-requests are
allowed to terminate immediately without any aschronous behaviour,
although I'm issuing asynchronous reads, i.e. ReadFile() returns
true. So the I changed the single-threaded code:
 
BOOL fRfRet;
 
for( unsigned par = 0; par < PARALLEL_DEGREE; par += !fRfRet )
{
aol[par].Offset = uid( mt ) & (DWORD)-(LONG)BLOCK_SIZE;
aol[par].OffsetHigh = 0;
aol[par].hEvent = NULL;
if( !(fRfRet = ReadFile( hFile, abBlock, BLOCK_SIZE, NULL,
&aol[par] ))
&& GetLastError() != ERROR_IO_PENDING )
return EXIT_FAILURE;
}
 
and in this place:
 
pol->Offset = uid( mt ) & (DWORD)-(LONG)BLOCK_SIZE;
pol->OffsetHigh = 0;
pol->hEvent = NULL;
for( ; ; )
if( ReadFile( hFile, abBlock, BLOCK_SIZE, NULL, pol ) )
continue;
else
if( GetLastError() == ERROR_IO_PENDING )
break;
else
return EXIT_FAILURE;
scott@slp53.sl.home (Scott Lurndal): May 02 01:28PM

>> shiny Pentium era build machine with 128...
 
>> It would probably work OK on current 32 core/64 thread machines :)
 
>I would still feel sorry for that single mutex. ;^)
 
Actually, it probably wouldn't work very well on current highly
threaded cores (e.g. Vulcan, with 128 threads). To obtain the
mutex, the requesting core must gain exclusive access to the
cache-line containing the mutex (linux, for example, will spin
in user-mode for a few iterations before blocking in the kernel).
 
The contention for this one, single, cache line can drag a system
to its knees rather quickly on a highly contended lock. Some
x86 processors will attempt to resolve starvation situations by
asserting a global bus lock which is very bad for system performance.
Andrey Karpov <karpov2007@gmail.com>: May 02 05:28AM -0700

The title of this article is a hint for the Visual Studio developers that they could benefit from the use of PVS-Studio static code analyzer. The article discusses the analysis results of the libraries in the recent Visual C++ 2017 release and gives advice on how to improve them and eliminate the bugs found. Read on to find out how the developers of Visual C++ Libraries shoot themselves in the foot: it's going to be interesting and informative.
 
Article: https://www.viva64.com/en/b/0502/
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 02 06:02AM -0700

On Tuesday, May 2, 2017 at 8:28:49 AM UTC-4, Andrey Karpov wrote:
> The title of this article is a hint for the Visual Studio developers that they could benefit from the use of PVS-Studio static code analyzer. The article discusses the analysis results of the libraries in the recent Visual C++ 2017 release and gives advice on how to improve them and eliminate the bugs found. Read on to find out how the developers of Visual C++ Libraries shoot themselves in the foot: it's going to be interesting and informative.
 
> Article: https://www.viva64.com/en/b/0502/
 
Are you here selling your product? Are you hoping we'll go and buy
your tool from this advertisement post?
 
How much does your product cost? I go to the Buy page and I don't
see a price, but only a "Contact us" reference. Do you sell it for
different prices to different people?
 
How much of a gain will I get by using it? Can you guarantee it will
take away my rheumatism and cure my arthritis? Will it help to regrow
the hair I've lost?
 
Or ... what does it do for me that makes it worth my approaching you
through the "Contact us" link and inquiring as to the price?
 
Thank you,
Rick C. Hodgin
Juha Nieminen <nospam@thanks.invalid>: May 02 07:12AM

> For example, over a dozen of web resources say "Virtual function call
> is resolved at run-time (dynamic binding) whereas the non-virtual
> member functions are resolved at compile time (static binding)".
 
The simplest explanation is an example:
 
//------------------------------------------------------
class Base
{
public:
void func1() const { std::cout << "func1\n"; }
virtual void func2() const = 0;
};
 
void foo(Base& obj)
{
obj.func1(); // Can be resolved at compile time
obj.func2(); // (Probably) resolved at runtime
}
//------------------------------------------------------
 
In the first case the compiler can see directly which function
implementation is being called, so it can put a direct function
call there (or even inline the implementation, if it sees it).
 
In the second case the compiler (usually) cannot know which
implementation will be called, so it uses some runtime logic
to find out. In practice this is just an indirect function call,
which isn't much heavier than a direct one.
 
(In most/all compiler implementations there's a point at the beginning
of 'obj' pointing to a static table created by the compiler, and at some
specific offset there will be a function pointer that the compiler
uses to make the function call. Each derived class will have its
own such virtual table, and objects of that type will have that
vtable pointer pointing to it.)
 
An usage example would be:
 
//------------------------------------------------------
class Derived1: public Base
{
public:
virtual void func2() const { std::cout << "derived1\n"; }
};
 
class Derived2: public Base
{
public:
virtual void func2() const { std::cout << "derived2\n"; }
};
 
int main()
{
Derived1 obj1;
Derived2 obj2;
foo(obj1); // will print "derived1"
foo(obj2); // will print "derived2"
}
//------------------------------------------------------
 
> Finally, is it possible that a virtual member function call is
> resolved at compile-time and not at run-time.
 
It's theoretically possible, but it doesn't affect the behavior of
the program in any way.
Juha Nieminen <nospam@thanks.invalid>: May 02 06:48AM

> Why I cannot create an object of type int(int,int) ? e.g.
> int(int,int) myFun;
 
The syntax to get a function pointer is a bit weird (and comes from C).
You have to write it as:
 
int(*myFun)(int, int);
 
In C++11 you kind of get closer by using the 'using' keyword, like so:
 
using Func = int(int, int);
Func* myFun = someFunction;
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: