Tuesday, October 1, 2019

Digest for comp.lang.c++@googlegroups.com - 25 updates in 5 topics

Frederick Gotham <cauldwell.thomas@gmail.com>: Oct 01 04:37AM -0700

This has taken me a lot longer than it should have, but I think I've put together a Makefile that will compile a program from all the C and C++ files in the current directory.
 
The C source files, *.c, become object files *.c.o
 
The C++ source files, *.cpp, become object files *.cpp.o
 
The very first time you compile your program, it creates dependency files (*.c.d and *.cpp.d), so if you change a header file and then go to recompile the program, it should only recompile the source files that included that one header file.
 
Here's what I've got so far:
 
PROGRAM = super_cool_prog
 
FLAGS_IN_COMMON = -pedantic -Wall -rdynamic -funwind-tables -fno-omit-frame-pointer -fdump-rtl-expand -Og -g
CXXFLAGS = $(FLAGS_IN_COMMON) -std=c++11
CFLAGS = $(FLAGS_IN_COMMON) -std=c99
 
CC = gcc
CXX = g++
 
SRC_FILES_C := $(shell find -maxdepth 1 -name '*.c')
SRC_FILES_CXX := $(shell find -maxdepth 1 -name '*.cpp')
 
OBJECTS_C := $(patsubst %.c,%.c.o,$(SRC_FILES_C))
OBJECTS_CXX := $(patsubst %.cpp,%.cpp.o,$(SRC_FILES_CXX))
 
OBJECTS = $(OBJECTS_C) $(OBJECTS_CXX)
 
.PHONY: all
all: $(PROGRAM)
 
$(PROGRAM): $(OBJECTS)
$(CXX) $(FLAGS_IN_COMMON) -o $@ $^
 
#This rule compiles the source files to object files
%.c.o: %.c %.c.d
$(CC) $(CFLAGS) -o $@ -c $<
 
%.cpp.o: %.cpp %.cpp.d
$(CXX) $(CXXFLAGS) -o $@ -c $<
 
#This rule makes dependencies files for the source files
.PRECIOUS: %.c.d
%.c.d: %.c
$(CC) -MM -MT '$(patsubst %.c,%.c.o,$<)' $< -MF $@
 
.PRECIOUS: %.cpp.d
%.cpp.d: %.cpp
$(CXX) -MM -MT '$(patsubst %.cpp,%.cpp.o,$<)' $< -MF $@
 
#This next line pulls in all the dependency files
include $(shell find -maxdepth 1 -name '*.d')
 
.PHONY: clean
clean:
rm -f $(OBJECTS) $(PROGRAM)
rm -f $(patsubst %.o,%.d,$(OBJECTS))
rm -f $(patsubst %.o,%.229r.expand,$(OBJECTS))
 
.PHONY: install
install: $(PROGRAM)
cp $< /usr/bin/
 
.PHONY: uninstall
uninstall:
rm -f /usr/bin/$(PROGRAM)
David Brown <david.brown@hesbynett.no>: Oct 01 02:48PM +0200

On 01/10/2019 13:37, Frederick Gotham wrote:
 
> The C++ source files, *.cpp, become object files *.cpp.o
 
> The very first time you compile your program, it creates dependency files (*.c.d and *.cpp.d), so if you change a header file and then go to recompile the program, it should only recompile the source files that included that one header file.
 
> Here's what I've got so far:
 
It's looking very good so far. I have made a few suggestions. They are
untested, but based on my own existing and working Makefiles. They may
also be dependent on GNU Make (but who uses anything else?).
 
> CXX = g++
 
> SRC_FILES_C := $(shell find -maxdepth 1 -name '*.c')
> SRC_FILES_CXX := $(shell find -maxdepth 1 -name '*.cpp')
 
Make's own file search will probably be more efficient:
 
SRC_FILES_C := $(wildcard *.c)
 
(Your method might be best for a more complex directory structure of
source files.)
 
 
> OBJECTS_C := $(patsubst %.c,%.c.o,$(SRC_FILES_C))
 
Shorter and faster alternative:
 
OBJECTS_C := $(SRC_FILES_C:.c=.o)
 
 
> $(CXX) -MM -MT '$(patsubst %.cpp,%.cpp.o,$<)' $< -MF $@
 
> #This next line pulls in all the dependency files
> include $(shell find -maxdepth 1 -name '*.d')
 
DEPENDS = $(OBJECTS:.o=.d)
 
-include $(DEPENDS)
 
Since the "-include" command ignores errors, you no longer need the
".PRECIOUS" and you don't have problems if some of your compilations are
failing to generate dependency files.
 
 
 
> .PHONY: uninstall
> uninstall:
> rm -f /usr/bin/$(PROGRAM)
 
You have two challenges left. First, the dependency files should be
updated automatically when their C or /header/ files change. Currently,
your dependencies are updated if the matching .c or .cpp file changes.
A simple method is:
 
 
HEADER_FILES := $(wildcard *.h)
 
%.c.d: %.c $(HEADER_FILES)
$(CC) -MM -MT '$(patsubst %.c,%.c.o,$<)' $< -MF $@
 
%.cpp.d: %.cpp $(HEADER_FILES)
$(CXX) -MM -MT '$(patsubst %.cpp,%.cpp.o,$<)' $< -MF $@
 
That will be a bit pessimistic and update dependency files more than
necessary, but that's better than doing so /less/ than necessarily.
 
A more advanced step would be something like:
 
%.c.d: %.c $(HEADER_FILES)
$(CC) -MM -MT '$(patsubst %.c,%.c.o,$<)' $< -MF $@
@sed -i 's,\(*\)\.o[ :]*,\1.o $@ : ,g' $@
 
I have not checked this "sed" line (and I can't read sed commands
fluently - this is based on lines from my own Makefiles, adapted as best
I can out of my head. I made my own "sed" commands based mainly on
googling and trial and error).
 
The idea is that you make the .d file itself dependent on the same files
the .o file is dependent upon.
 
 
I also like to make all the file generations dependent on "Makefile" too.
 
 
 
Your next challenge is to separate the source code directory (or
directories) from the directories for working files (.o, .d). I'll
leave that one for homework.
James Kuyper <jameskuyper@alumni.caltech.edu>: Sep 30 09:36PM -0400

On 9/30/19 12:55 PM, Soviet_Mario wrote:
 
>> Since C99.
 
> for curiosity, this feature has one or more of the
> limitations I feared ... or even none of them ?
 
There are several limitations on VLAs:
They were not part of standard C until C99, and became optional in
C2011. A C2011 implementation that does not support them will pre#define
__STDC_NO_VLA__ with a value of 1. They have never yet been part of
standard C++.
 
The type name in a compound literal is not allowed ot be a VLA (6.5.2.5p1).
 
A VLA can be declared with a size that is unspecified - this is
specified by using "*" for the size, and can only be done in the
declaration of a function parameter that is NOT part of the definition
of that function (6.7.2p4).
 
The expression for the size of a VLA must be an integer expression with
a value greater than 0 (6.7.2p5).
 
"Where a size expression is part of the operand of a sizeof operator and
changing the value of the size expression would not affect the result of
the operator, it is unspecified whether or not the size expression is
evaluated." (6.7.2p5)
 
Thus, portable code cannot rely upon the value of being changed (or
unchanged) by evaluation of sizeof(int[n++]) - as a general rule, that
would make it a bad idea to write such an expression.
 
"If, in the nested sequence of declarators in a full declarator, there
is a declarator specifying a variable length array type, the type
specified by the full declarator is said to be variably modified.
Furthermore, any type derived by declarator type derivation from a
variably modified type is itself variably modified." (6.7.6p3)
 
For instance, int (*vla)[n] declares a pointer to a VLA, but is not
itself a VLA. But it is a variably modified type .
 
A typedef for a VM type cannot be redefined, not even to the same type
(6.7p3).
 
"A member of a structure or union may have any complete object type
other than a variably modified type." (6.7.2.1p9)
 
"If an identifier is declared as having a variably modified type, it
shall be an ordinary identifier (as defined in 6.2.3), have no linkage,
and have either block scope or function prototype scope. If an
identifier is declared to be an object with static or thread storage
duration, it shall not have a variable length array type." (6.7.6.2p2)
 
"If a typedef name specifies a variably modified type then it shall have
block scope." (6.7.8p2)
 
"If a switch statement has an associated case or default label within
the scope of an identifier with a variably modified type, the entire
switch statement shall be within the scope of that identifier." (6.8.4.2p2)
 
"A goto statement shall not jump from outside the scope of an identifier
having a variably modified type to inside the scope of that identifier."
(6.8.6.1)
 
"... if the invocation of the setjmp macro was within the scope of an
identifier with variably modified type and execution has left that scope
in the interim, the behavior [of longjmp()] is undefined." (7.13.2.1p2)
Robert Wessel <robertwessel2@yahoo.com>: Oct 01 12:18AM -0500

On Mon, 30 Sep 2019 19:16:19 +0200, Bonita Montero
 
>> As of C11, they are optional.
 
>And with C++ you can ask the compiler via __STDC_NO_VLA__ if VLAs
>are not supported.
 
 
Are C++ compilers actually obligated to define _STDC_NO_VLA_?
Bonita Montero <Bonita.Montero@gmail.com>: Oct 01 07:19AM +0200

>> comitted?
 
> The compiler does this to ensure the alloca'd region doesn't extend past
> the stack guard page.
 
1. Not the compiler does do this but the OS.
2. The OS could do this with a single guard-page or maybe by reserving
a larger number of pages at the end of the stack.
 
> The kernel can handle noncontiguous stack access, ...
 
No, It can't as I said. I'm talking about Windows.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 01 07:32AM +0200

> as to design Windows that it would also recoginize noncontignous acces-
> ses to the stack-pages? Are these pages handled are like being over-
> comitted?
 
I just wrote a little program:
 
1. #include <Windows.h>
2. #include <iostream>
3. #include <thread>
4. #include <mutex>
5. #include <vector>
6. #include <cstddef>
7. #include <functional>
8.
9. using namespace std;
10.
11. int main()
12. {
13. size_t const ALLOCSIZE = (size_t)1 << 30;
14. void *p = VirtualAlloc( nullptr, ALLOCSIZE, MEM_RESERVE
| MEM_COMMIT, PAGE_READWRITE );
15. memset( p, 0, ALLOCSIZE );
16.
17. auto threadFn = []( mutex &mtx, condition_variable &cv, bool
&start )
18. {
19. auto getSignal = []( mutex &mtx, condition_variable &cv,
bool &start )
20. {
21. unique_lock<mutex> ul( mtx );
22. while( !start )
23. cv.wait( ul );
24. };
25. getSignal( ref( mtx ), ref( cv ), ref( start ) );
26. __try
27. {
28. size_t const PAGESIZE = 0x1000;
29. char volatile c[1], *p;
30. for( p = c; ; *p, p -= PAGESIZE );
31. }
32. __except( EXCEPTION_EXECUTE_HANDLER )
33. {
34. }
35. Sleep( INFINITE );
36. };
37. mutex mtx;
38. condition_variable cv;
39. bool start = false;
40. vector<thread> vt;
41.
42. for( size_t i = 0; i != 1000; ++i )
43. vt.emplace_back( threadFn, ref( mtx ), ref( cv ), ref( start
) );
44. {
45. unique_lock<mutex> ul( mtx );
46. start = true;
47. cv.notify_all();
48. }
49.
50. Sleep( INFINITE );
51. }
52.
 
If I stop at line 15, I can see with the Process Explorer that the
virtual size as well as the private bytes of the process is raised
by 1GB. So There's no overcommit. The memset at line 15 doesn't
change this.
Then I spawn 1.000 threads and they first gonna wait for a condvar.
The threads get their standard threadsize set by the linker, which
is 1MB. At the point where they wait the virtual size of the pro-
cess is raised by about 1GB, but the private size is raised only
a small amount; so there's definitely a differnce in the commit
-behaviour between stack-allocation and VirtualAlloc / MEM_RESERVE
| MEM_COMMIT. When I waken the threads the read the whole stack
down to the guard page and the access to this page is catched by
a SEH-handler (I had to pack the waiting-part in a lambda because
I can't use functions with unwind-handlers that are using SEH).
So Windows is definitely overcommitting stacks.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 01 07:39AM +0200

> uhm, I didn't mean THAT kind of risk (unavoidable), but the possible
> difficulties in defining variables beyond the point of declaration of
> the variable-size array.
 
The compiler usually collects the size of all the "static" variables in
the stack and reserves the space for them at the function-prolog. The
VLA-spaces are handled within the function at the point where they are
reserved (coudln't be handled differently because their size is only
known at the point where they are reserved).
Bonita Montero <Bonita.Montero@gmail.com>: Oct 01 07:41AM +0200

> mov %rsp, %rax # rax now has starting address of alloca() region
 
The compiler usually uses RPB to remember the frame-pointer-address
at the prolog of the function. EBP is more suitable because it can
be restored in one step by the x86 LEAVE-instruction.
 
Bonita Montero <Bonita.Montero@gmail.com>: Oct 01 07:43AM +0200

>> And with C++ you can ask the compiler via __STDC_NO_VLA__ if VLAs
>> are not supported.
 
> Are C++ compilers actually obligated to define _STDC_NO_VLA_?
 
It's at least not part of the C++17-standard.
Paavo Helde <myfirstname@osa.pri.ee>: Oct 01 09:08AM +0300

On 1.10.2019 8:32, Bonita Montero wrote:
 
> so there's definitely a differnce in the commit
> -behaviour between stack-allocation and VirtualAlloc / MEM_RESERVE
> | MEM_COMMIT.
 
Yes, it looks like the whole stack space is reserved with MEM_RESERVE,
but is not committed with MEM_COMMIT.
 
> When I waken the threads the read the whole stack
> down to the guard page and the access to this page is catched by
> a SEH-handler
 
No, what happens that the guard page is moved through the whole stack
until it reaches the end of it. The purpose of the guard page approach
is exactly to avoid the need to commit extra stack space until it
becomes needed.
 
> So Windows is definitely overcommitting stacks.
 
You cannot over-commit something what is not committed.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 01 08:35AM +0200

>> a SEH-handler
 
> No, what happens that the guard page is moved through the whole stack
> until it reaches the end of it. ...
 
The guard-page will stop moving at the end.
 
>> So Windows is definitely overcommitting stacks.
 
> You cannot over-commit something what is not committed.
 
This is a flavour of overcommitting because I get a commit by touching
a page and the application will crash if the "dynamic commmit" fails.
Melzzzzz <Melzzzzz@zzzzz.com>: Oct 01 07:03AM

>>> length array, or a pre-allocated memory block on the heap?
 
>> VLA elliminates need for alloca...
 
> C++ hasn't VLAs.
 
No, neiter has alloca...
 
 
 
 
 
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
David Brown <david.brown@hesbynett.no>: Oct 01 09:38AM +0200

On 30/09/2019 22:28, Joe Pfeiffer wrote:
> were writing the compiler that would be my first approach (since, as you
> suggest, that would permit the other variables to be accessed through
> constant offsets).
 
Exactly. It is a likely that the allocation would be handled something
like that. But the compiler can arrange the details in any way it deems
best.
 
Alternatives include allocating some fixed frame variables first, then
copying the stack pointer to a frame pointer (call it "fp"). Then the
alloca() or VLA adds to the stack, then there is some more stack data
(maybe another VLA or alloca() ). The first data can be accessed as "fp
+ offset", later data as "sp + offset". Intermediary anchor points can
be saved as necessary.
 
Mixing multiple VLA's and alloca's in the same function is likely to
give you inefficient code and wasted stack space (alloca data lives
until the end of the function, VLA's live until the end of the block).
But the compiler's prime job is to give you correct object code, and it
should handle that okay.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 01 10:57AM +0200

>>> VLA elliminates need for alloca...
 
>> C++ hasn't VLAs.
 
> No, neiter has alloca...
 
Doesn't matter since most compilers support alloca().
Keith Thompson <kst-u@mib.org>: Oct 01 02:42AM -0700

Robert Wessel <robertwessel2@yahoo.com> writes:
[...]
> Are C++ compilers actually obligated to define _STDC_NO_VLA_?
 
No, __STDC_NO_VLA__ (note the double underscores) is specific to C11 and
later. C++ doesn't support VLAs at all, so there's no need for a C++
compiler to indicate its lack of support, and the C++ standard doesn't
require it to do so.
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 01 08:11AM -0400

On 10/1/19 5:42 AM, Keith Thompson wrote:
> later. C++ doesn't support VLAs at all, so there's no need for a C++
> compiler to indicate its lack of support, and the C++ standard doesn't
> require it to do so.
 
I'm sure you know this, but for the sake of other readers, I'd like to
point out that the fact that __STDC_NO_VLA__ is a C-specific macro does
not, in itself, prevent the C++ standard from saying anything about it.
The C++ standard simply failed to do so. It has said things about other
C pre#defined macros.
 
The C++ standard mandates the setting of __STDC_HOSTED__ to either 0 or
1, as appropriate, and allows the setting of __STDC_MB_MIGHT_NEQ_WC__,
__STDC__, __STDC_VERSION__, and __STDC_ISO_10646__. If
__STDC_MB_MIGHT_NEQ_WC__ is pre#defined, it's required expand to the
integer literal 1, and if __STDC_ISO_10646__ is pre#defined, it's
required to expand to "An integer literal of the form yyyymmL".
Frederick Gotham <cauldwell.thomas@gmail.com>: Oct 01 01:14AM -0700

On Monday, September 30, 2019 at 3:48:45 PM UTC+1, David Brown wrote:
> you are supposed to buy, is not theft. It is illegal, but it is not
> theft. And it is certainly not piracy.
 
> I hope that answers your original question.
 
 
So when does making unlicensed copies become piracy? Does it become piracy when you try to sell these unlicensed copied to make a profit?
David Brown <david.brown@hesbynett.no>: Oct 01 10:54AM +0200

On 01/10/2019 10:14, Frederick Gotham wrote:
>> theft. And it is certainly not piracy.
 
>> I hope that answers your original question.
 
> So when does making unlicensed copies become piracy?
 
Never.
 
> Does it become piracy when you try to sell these unlicensed copied to make a profit?
 
No.
 
It becomes piracy when you attack the ship carrying the book and steal
it physically by violence or threats of violence.
 
 
There can be different levels of law-breaking depending on whether you
are copying for private use, copying to sell, etc. In particular, in
most jurisdictions (AFAIK), downloading an unlicensed copy of
copyrighted works is illegal but not a crime. Selling it might make it
a crime. And in some places, making it available for download is also a
crime, as can breaking encryption for the purposes of evading licensing.
 
But it is never theft, and never piracy.
"Öö Tiib" <ootiib@hot.ee>: Oct 01 02:48AM -0700

On Tuesday, 1 October 2019 11:55:07 UTC+3, David Brown wrote:
> a crime. And in some places, making it available for download is also a
> crime, as can breaking encryption for the purposes of evading licensing.
 
> But it is never theft, and never piracy.
 
I have observed that unauthorized use or reproduction of another's work
is now also called "piracy" in English quite officially. It is indeed
blowing severity of that misconduct committed out of proportions.
David Brown <david.brown@hesbynett.no>: Oct 01 01:25PM +0200

On 01/10/2019 11:48, Öö Tiib wrote:
 
> I have observed that unauthorized use or reproduction of another's work
> is now also called "piracy" in English quite officially. It is indeed
> blowing severity of that misconduct committed out of proportions.
 
Yes, it is certainly true that people talk about "music piracy" or
"software piracy". The term was popularised by big copyright owners as
a way of scaring people who make unlicensed copies, and continues to be
used by people who are either ignorant of the matter, or don't think the
terms used are important enough to bother being accurate. (We are only
having this discussion because someone asked for the details.)
 
There are even some public figures who have made fools of themselves by
comparing "software pirates" or "media pirates" to /real/ pirates on the
Somalian coast.
David Brown <david.brown@hesbynett.no>: Oct 01 09:20AM +0200

On 30/09/2019 21:38, Richard wrote:
 
> The programming community is as inclusive as it needs to be in that
> it doesn't exclude anyone. You got the skills and the motivation
> and you're in. It's as simple as that.
 
It is a slightly odd situation. Individual programmers are, mostly,
inclusive in that sense. There are a few who mistreat others from
prejudice (I've seen it occasionally in c.l.c and c.l.c++, but only
rarely). Basically, most programmers are simply not particularly
interested in others' appearances, personal life, etc. - programmers are
rarely the most social of people, and they are relatively immune to the
social pressures that are often behind prejudice.
 
However, when someone looks from the outside at a community of
programmers, there is a strong homogeneity about it - the solid majority
will be white males, for example. (Obviously the dominant racial
background will be different outside of North America, Europe and
Australasia, but the gender dominance will not.) This is a hard barrier
to entry for people who don't fit the programmer norm. If a young woman
wants to study programming at university, she will be faced with "Why do
you want to be a programmer? It's a guy thing - for nerds who live in
their parent's basement". Other programmers either don't care, or are
happy to see a bit of variety in their ranks.
 
That is why I say that the programming world has image problems - /not/
that programmers themselves are not inclusive people.
 
> is a distant memory to anyone who was alive at the time.
 
> At this point, the barrier is one of individual motivation and
> interest and nothing more.
 
There is no barrier that we, the programmers themselves, have erected.
Yet there is still a barrier.
 
(You see similar barriers in many other fields.)
"Öö Tiib" <ootiib@hot.ee>: Oct 01 12:58AM -0700

On Tuesday, 1 October 2019 10:20:29 UTC+3, David Brown wrote:
> happy to see a bit of variety in their ranks.
 
> That is why I say that the programming world has image problems - /not/
> that programmers themselves are not inclusive people.
 
I see plenty of female programmers here, in my previous team there was
3. And on the other hand is unlikely that schoolboy who wears dress
can change gender-related stereotypes in calcificated brains of
university teachers.
David Brown <david.brown@hesbynett.no>: Oct 01 10:58AM +0200

On 01/10/2019 09:58, Öö Tiib wrote:
>> that programmers themselves are not inclusive people.
 
> I see plenty of female programmers here, in my previous team there was
> 3.
 
The world progresses (at least sometimes!).
 
> And on the other hand is unlikely that schoolboy who wears dress
> can change gender-related stereotypes in calcificated brains of
> university teachers.
 
True. But it might inspire other "differently normal" people that
/they/ don't have to conform to stereotypes. I don't expect it to make
a big difference, but little steps add up over time.
woodbrian77@gmail.com: Sep 30 08:21PM -0700

> that can be improved on, but if you want to get into the code, that's
> good. Maybe you have a suggestion about how to organize things
> differently, etc. Thank you in advance.
 
Currently my code generator is a TCP server. I've been
looking into some alternatives to that. I'd like to use
Wireguard for encryption so something like Quic might not
work for me. I've never used SCTP or DCCP. Would those
work with Wireguard? I need it to work on Posix including
FreeBSD and Linux. Any advice for choosing between SCTP
and DCCP?
 
 
Brian
Ebenezer Enterprises
http://webEbenezer.net
woodbrian77@gmail.com: Sep 30 08:34PM -0700

> work with Wireguard? I need it to work on Posix including
> FreeBSD and Linux. Any advice for choosing between SCTP
> and DCCP?
 
I guess DCCP doesn't provide reliable in-order delivery so
that's not an option. I'll try SCTP for now.
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: