Topic: Ideas for C: What could C and systems level APIs do
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 29 Jan 2014 06:03:33 -0800 (PST)
Raw View
------=_Part_5856_298459.1391004213845
Content-Type: text/plain; charset=UTF-8
Most modern technology including C++ is still built ontop of C. This is not
likely to change for a long time, if ever. While C is a solid foundation,
there are a few warts. These gaps in the C API force all of the higher
level constructs to perform workarounds, to the detriment of software
interfaces and performance.
This post might belong in a C forum, but I wanted to ask. What do you think
C could change to make the world better for C++ and/or other languages and
technologies?
Here are 2 ideas:
1) Extend the memory interface with alloc_expand();
I'd love to see the C standard adopt a variant the following function in
their malloc() API.
//Tries to resize p in place to newlen bytes. If successful, returns p,
otherwise returns NULL and the memory pointed to by p is unmodifed. Returns
NULL if p is NULL.
void* alloc_expand(void* p, size_t newlen);
Why? Because we should be able to take advantage of this memory
optimization for contiguous memory layout data structures such as
std::vector and std::string. A dynamic array is the most fundamental data
structure in any language. Contiguous memory layout is key for performance
on modern hardware.
There have been several proposals and discussions about having some form of
realloc() in the standard.
Facebook even went as far as to define their own folly::IsRelocatable type
trait to be able to tag types that are safe to memcopied with realloc().
They have also benchmarked and shown that realloc() is a very useful
optimization for dynamicly resizing array.
https://github.com/facebook/folly/blob/master/folly/FBVector.h
https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md
The D language also supports this optimization on their built in array
type. They even go as far as to ban objects with internal pointers to
ensure every object can be relocated. I'm assuming this is so that they can
take advantage of realloc() and memcpy().
In my opinion, this is completely misguided and absolutely the wrong way to
go. The problem is not that we should support realloc(). The problem is
that the realloc() interface is fundamentally broken. I'd like to write a
proposal about this in more detail, but suffice to say, I think realloc()
is a complete non-starter and we need a more elementary primitive for this
operation.
With realloc(), we do the following:
1. Resize in place if we can, or
2. malloc() a new buffer
3. memcpy() the contents to the new buffer
4. free() the old buffer
5. return the new buffer
It is step 3 that breaks C++ as objects need to use their move/copy
constructors to safely be relocated. By providing a primitive that only
performs step 1, we impose the rest of this realloc algorthm onto the
caller, allowing them to replace step 3 as needed. With this approach,
there is no need to pollute code bases with std::is_relocatable() type
traits or artificially limit the realloc() optimization to trivially
copyable types.
So why do I say this support should be in C? Because like it or not C is
still the low level foundation underneath C++ and many different
technologies. While my alloc_expand() has limited usefulness for C itself,
it has manifold applications for C++ and other higher level languages built
on top of C.
There is another major practical reason that having this feature in C would
be of great benefit to everyone. Most of the memory allocation libraries
such as jemalloc(), dlmalloc(), tcmalloc(), and friends are written to the
C interface. The simple reason being that writing to the C interface
automatically gives you support in both C and C++. Adding alloc_expand() to
the C specification would encourage everyone writing a memory allocator to
support the primitive and guarantee support to C++ and all other higher
level constructs built ontop this simple C interface.
Any implementation that supports realloc() can easily add alloc_expand().
For a memory allocation strategy where resizing in place does not make
sense, alloc_expand() can always return NULL.
2) First class support for non-null terminated strings
I'm a huge fan of string_view. I can't wait for this style of string
processing to be the norm.
Why I like string_view:
- std::string interfaces have serious performance issues with creating
temporaries for all kinds of operations which require memory allocations.
std::string is also "infectious", once one of your strings is a std::string
everything that touches its tends to want to become a std::string as well.
- Null termination sucks too. Multiple layers of const char* interfaces
often require redundant strlen() computations as the most common interfaces
only accept a const char* and not a length. Remembering to null terminate
character arrays is a specific skill that must be trained with discipline.
Doing operations on the end of the string such as removing a suffix are now
linear time.
Quick question. How do you write a File class which uses string_view to
open a file on unix?
bool File::open(sting_view fname, File::Flags flags) {
std::string sfilename = fname; //<-Do a memory allocation and copy the
whole filename just because we need a null terminator
int posix_flags = File::_flags_to_posix(flags);
_fd = ::open(sfilename.c_str(), posix_flags); //<-Likely the first thing
this does is call strlen(), and then proceed to do the file opening.
return _fd >= 0;
}
Not only is this less efficient, its also painful to have to go through
these contortions. More code means more bugs, especially for beginners. Now
we have to allocate memory [O(1) + C] (<- constant time, but the constant
is large) and then make a useless copy O(N), the open() call itself will
likely call strlen() O(N).
I also found this interesting bit on the zeromq page:
http://zguide.zeromq.org/page:all#A-Minor-Note-on-Strings
Specifically this code:
*static* char *
s_recv (void *socket) {
char buffer [256];
int size = zmq_recv (socket, buffer, 255, 0);
*if* (size == -1)
*return* NULL;
*if* (size > 255)
size = 255;
buffer [size] = 0;
*return* strdup (buffer);
}
I don't know about you, but that code makes me want to run away and hide.
That's a lot of contortions (with possible off by 1 errors) just to deal
with the fact that C forces you to use null terminated strings. The worse
being that instead of just returning a pointer to the buffer already
managed by zmq, we have to allocate a string and impose memory management
on the caller.
These are the kinds of contortions library implementors are forced to deal
with when working with C APIs. When string_view becomes the defacto
standard for a "const reference to a variable length string", the library
implementors will be forced to do these null and non-null conversions.
So what would be nice is to augment the set of string functions with new
functions which take a pointer and a length. Making non-null terminated
strings viable in the C world. This would optimally require support from
the C standard as well as other common standards such as POSIX. Support in
the C standard would then encourage support in other C libraries, enhancing
interoperability all around.
Some examples:
char* strdup_l(const char* s, size_t len);
FILE* fopen_l(const char* filename, size_t len, const char* mode, size_t
mlen);
int open_l(const char* pathname, size_t len, int flags, mode_t mode);
DIR* opendir_l(const char* pathname, size_t len);
void* dlopen_l(const char* filename, size_t len, int flag);
------------------------------
What do you think C could do to help C++ and other high level languages and
technologies built ontop of C?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5856_298459.1391004213845
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Most modern technology including C++ is still built o=
ntop of C. This is not likely to change for a long time, if ever. While C i=
s a solid foundation, there are a few warts. These gaps in the C API force =
all of the higher level constructs to perform workarounds, to the detriment=
of software interfaces and performance.</div><div><br></div><div>This post=
might belong in a C forum, but I wanted to ask. What do you think C could =
change to make the world better for C++ and/or other languages and technolo=
gies?</div><div><br></div><div>Here are 2 ideas:</div><div><br></div>1) Ext=
end the memory interface with <span style=3D"font-size: 13px;">alloc_e=
xpand();</span><div><div><br></div><div>I'd love to see the C standard adop=
t a variant the following function in their malloc() API.</div><div><br></d=
iv><div>//Tries to resize p in place to newlen bytes. If successful, return=
s p, otherwise returns NULL and the memory pointed to by p is unmodifed. Re=
turns NULL if p is NULL.</div><div>void* alloc_expand(void* p, size_t newle=
n);</div><div><br></div><div>Why? Because we should be able to take advanta=
ge of this memory optimization for contiguous memory layout data structures=
such as std::vector and std::string. A dynamic array is the most fun=
damental data structure in any language. Contiguous memory layout is key fo=
r performance on modern hardware.</div><div><br></div><div>There have been =
several proposals and discussions about having some form of realloc() in th=
e standard. </div><div><br></div><div>Facebook even went as far as to =
define their own folly::IsRelocatable type trait to be able to tag types th=
at are safe to memcopied with realloc(). They have also benchmarked and sho=
wn that realloc() is a very useful optimization for dynamicly resizing arra=
y. </div></div><div><br></div><div><a href=3D"https://github.com/faceb=
ook/folly/blob/master/folly/FBVector.h">https://github.com/facebook/folly/b=
lob/master/folly/FBVector.h</a><br></div><div><a href=3D"https://github.com=
/facebook/folly/blob/master/folly/docs/FBVector.md">https://github.com/face=
book/folly/blob/master/folly/docs/FBVector.md</a><br></div><div><br></div><=
div>The D language also supports this optimization on their built in array =
type. They even go as far as to ban objects with internal pointers to ensur=
e every object can be relocated. I'm assuming this is so that they can take=
advantage of realloc() and memcpy().</div><div><br></div><div>In my opinio=
n, this is completely misguided and absolutely the wrong way to go. The pro=
blem is not that we should support realloc(). The problem is that the reall=
oc() interface is fundamentally broken. I'd like to write a proposal about =
this in more detail, but suffice to say, I think realloc() is a complete no=
n-starter and we need a more elementary primitive for this operation.</div>=
<div><br></div><div>With realloc(), we do the following:</div><div><ol><li>=
<span style=3D"line-height: normal;">Resize in place if we can, or</span></=
li><li><span style=3D"line-height: normal;">malloc() a new buffer</span></l=
i><li><span style=3D"line-height: normal;">memcpy() the contents to the new=
buffer</span></li><li><span style=3D"line-height: normal;">free() the old =
buffer</span></li><li><span style=3D"line-height: normal;">return the new b=
uffer</span></li></ol></div><div>It is step 3 that breaks C++ as objects ne=
ed to use their move/copy constructors to safely be relocated. By providing=
a primitive that only performs step 1, we impose the rest of this realloc =
algorthm onto the caller, allowing them to replace step 3 as needed. With t=
his approach, there is no need to pollute code bases with std::is_relocatab=
le() type traits or artificially limit the realloc() optimization to trivia=
lly copyable types.</div><div><br></div><div>So why do I say this support s=
hould be in C? Because like it or not C is still the low level foundation u=
nderneath C++ and many different technologies. While my alloc_expand() has =
limited usefulness for C itself, it has manifold applications for C++ and o=
ther higher level languages built on top of C.</div><div><br></div><div>The=
re is another major practical reason that having this feature in C would be=
of great benefit to everyone. Most of the memory allocation libraries such=
as jemalloc(), dlmalloc(), tcmalloc(), and friends are written to the C in=
terface. The simple reason being that writing to the C interface automatica=
lly gives you support in both C and C++. Adding alloc_expand() to the C spe=
cification would encourage everyone writing a memory allocator to support t=
he primitive and guarantee support to C++ and all other higher level constr=
ucts built ontop this simple C interface.</div><div><br></div><div>Any impl=
ementation that supports realloc() can easily add alloc_expand(). For a mem=
ory allocation strategy where resizing in place does not make sense, alloc_=
expand() can always return NULL.</div><div><br></div><div>2) First class su=
pport for non-null terminated strings</div><div><br></div><div>I'm a huge f=
an of string_view. I can't wait for this style of string processing to be t=
he norm. </div><div><br></div><div>Why I like string_view:</div><div><=
ul><li><span style=3D"font-size: 13px;">std::string interfaces have serious=
performance issues with creating temporaries for all kinds of operations w=
hich require memory allocations. std::string is also "infectious", once one=
of your strings is a std::string everything that touches its tends to want=
to become a std::string as well.</span></li><li><span style=3D"font-size: =
13px;">Null termination sucks too. Multiple layers of const char* interface=
s often require redundant strlen() computations as the most common interfac=
es only accept a const char* and not a length. Remembering to null terminat=
e character arrays is a specific skill that must be trained with discipline=
.. Doing operations on the end of the string such as removing a suffix are n=
ow linear time.</span></li></ul></div><div><br></div><div>Quick question. H=
ow do you write a File class which uses string_view to open a file on unix?=
</div><div><br></div><div>bool File::open(sting_view fname, File::Flags fla=
gs) {</div><div> std::string sfilename =3D fname; //<-Do a memory =
allocation and copy the whole filename just because we need a null terminat=
or</div><div> int posix_flags =3D File::_flags_to_posix(flags);</div>=
<div> _fd =3D ::open(sfilename.c_str(), posix_flags); //<-Likely t=
he first thing this does is call strlen(), and then proceed to do the file =
opening.</div><div> return _fd >=3D 0;<br>}</div><div><br></div><d=
iv>Not only is this less efficient, its also painful to have to go through =
these contortions. More code means more bugs, especially for beginners. Now=
we have to allocate memory [O(1) + C] (<- constant time, but the consta=
nt is large) and then make a useless copy O(N), the open() call itself will=
likely call strlen() O(N).</div><div><br></div><div>I also found this inte=
resting bit on the zeromq page:</div><div><a href=3D"http://zguide.zeromq.o=
rg/page:all#A-Minor-Note-on-Strings">http://zguide.zeromq.org/page:all#A-Mi=
nor-Note-on-Strings</a><br></div><div><br></div><div>Specifically this code=
:</div><div><span style=3D"font-family: 'Andale Mono', 'Courier New', Couri=
er, monospace; line-height: 16px; background-color: rgb(238, 238, 238); col=
or: rgb(0, 128, 0);"><strong>static</strong></span><span style=3D"color: rg=
b(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monospace; =
line-height: 16px; background-color: rgb(238, 238, 238);"> </span><spa=
n style=3D"font-family: 'Andale Mono', 'Courier New', Courier, monospace; l=
ine-height: 16px; background-color: rgb(238, 238, 238); color: rgb(176, 0, =
64);">char</span><span style=3D"color: rgb(0, 0, 0); font-family: 'Andale M=
ono', 'Courier New', Courier, monospace; line-height: 16px; background-colo=
r: rgb(238, 238, 238);"> </span><span style=3D"font-family: 'Andale Mo=
no', 'Courier New', Courier, monospace; line-height: 16px; background-color=
: rgb(238, 238, 238); color: rgb(102, 102, 102);">*</span><br style=3D"colo=
r: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monosp=
ace; line-height: 16px; background-color: rgb(238, 238, 238);"><span style=
=3D"font-family: 'Andale Mono', 'Courier New', Courier, monospace; line-hei=
ght: 16px; background-color: rgb(238, 238, 238); color: rgb(0, 0, 255);">s_=
recv</span><span style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', =
'Courier New', Courier, monospace; line-height: 16px; background-color: rgb=
(238, 238, 238);"> (</span><span style=3D"font-family: 'Andale Mono', =
'Courier New', Courier, monospace; line-height: 16px; background-color: rgb=
(238, 238, 238); color: rgb(176, 0, 64);">void</span><span style=3D"color: =
rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monospace=
; line-height: 16px; background-color: rgb(238, 238, 238);"> </span><s=
pan style=3D"font-family: 'Andale Mono', 'Courier New', Courier, monospace;=
line-height: 16px; background-color: rgb(238, 238, 238); color: rgb(102, 1=
02, 102);">*</span><span style=3D"color: rgb(0, 0, 0); font-family: 'Andale=
Mono', 'Courier New', Courier, monospace; line-height: 16px; background-co=
lor: rgb(238, 238, 238);">socket) {</span><br style=3D"color: rgb(0, 0, 0);=
font-family: 'Andale Mono', 'Courier New', Courier, monospace; line-height=
: 16px; background-color: rgb(238, 238, 238);"><tt style=3D"font-family: 'A=
ndale Mono', 'Courier New', Courier, monospace; color: rgb(0, 0, 0); line-h=
eight: 16px; background-color: rgb(238, 238, 238);"><span style=3D"white-sp=
ace: pre-wrap;"> </span></tt><span style=3D"font-family: 'Andale Mono', =
'Courier New', Courier, monospace; line-height: 16px; background-color: rgb=
(238, 238, 238); color: rgb(176, 0, 64);">char</span><span style=3D"color: =
rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monospace=
; line-height: 16px; background-color: rgb(238, 238, 238);"> buffer&nb=
sp;</span><span style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', '=
Courier New', Courier, monospace; line-height: 16px; background-color: rgb(=
238, 238, 238); white-space: pre-wrap;">[</span><span style=3D"font-family:=
'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px; backg=
round-color: rgb(238, 238, 238); color: rgb(102, 102, 102);">256</span><spa=
n style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', =
Courier, monospace; line-height: 16px; background-color: rgb(238, 238, 238)=
; white-space: pre-wrap;">]</span><span style=3D"color: rgb(0, 0, 0); font-=
family: 'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px=
; background-color: rgb(238, 238, 238);">;</span><br style=3D"color: rgb(0,=
0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monospace; line=
-height: 16px; background-color: rgb(238, 238, 238);"><tt style=3D"font-fam=
ily: 'Andale Mono', 'Courier New', Courier, monospace; color: rgb(0, 0, 0);=
line-height: 16px; background-color: rgb(238, 238, 238);"><span style=3D"w=
hite-space: pre-wrap;"> </span></tt><span style=3D"font-family: 'Andale =
Mono', 'Courier New', Courier, monospace; line-height: 16px; background-col=
or: rgb(238, 238, 238); color: rgb(176, 0, 64);">int</span><span style=3D"c=
olor: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, mon=
ospace; line-height: 16px; background-color: rgb(238, 238, 238);"> siz=
e </span><span style=3D"font-family: 'Andale Mono', 'Courier New', Cou=
rier, monospace; line-height: 16px; background-color: rgb(238, 238, 238); c=
olor: rgb(102, 102, 102);">=3D</span><span style=3D"color: rgb(0, 0, 0); fo=
nt-family: 'Andale Mono', 'Courier New', Courier, monospace; line-height: 1=
6px; background-color: rgb(238, 238, 238);"> zmq_recv (socket, buffer,=
</span><span style=3D"font-family: 'Andale Mono', 'Courier New', Cour=
ier, monospace; line-height: 16px; background-color: rgb(238, 238, 238); co=
lor: rgb(102, 102, 102);">255</span><span style=3D"color: rgb(0, 0, 0); fon=
t-family: 'Andale Mono', 'Courier New', Courier, monospace; line-height: 16=
px; background-color: rgb(238, 238, 238);">, </span><span style=3D"fon=
t-family: 'Andale Mono', 'Courier New', Courier, monospace; line-height: 16=
px; background-color: rgb(238, 238, 238); color: rgb(102, 102, 102);">0</sp=
an><span style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier=
New', Courier, monospace; line-height: 16px; background-color: rgb(238, 23=
8, 238);">);</span><br style=3D"color: rgb(0, 0, 0); font-family: 'Andale M=
ono', 'Courier New', Courier, monospace; line-height: 16px; background-colo=
r: rgb(238, 238, 238);"><tt style=3D"font-family: 'Andale Mono', 'Courier N=
ew', Courier, monospace; color: rgb(0, 0, 0); line-height: 16px; background=
-color: rgb(238, 238, 238);"><span style=3D"white-space: pre-wrap;"> </s=
pan></tt><span style=3D"font-family: 'Andale Mono', 'Courier New', Courier,=
monospace; line-height: 16px; background-color: rgb(238, 238, 238); color:=
rgb(0, 128, 0);"><strong>if</strong></span><span style=3D"color: rgb(0, 0,=
0); font-family: 'Andale Mono', 'Courier New', Courier, monospace; line-he=
ight: 16px; background-color: rgb(238, 238, 238);"> (size </span>=
<span style=3D"font-family: 'Andale Mono', 'Courier New', Courier, monospac=
e; line-height: 16px; background-color: rgb(238, 238, 238); color: rgb(102,=
102, 102);">=3D=3D</span><span style=3D"color: rgb(0, 0, 0); font-family: =
'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px; backgr=
ound-color: rgb(238, 238, 238);"> </span><span style=3D"font-family: '=
Andale Mono', 'Courier New', Courier, monospace; line-height: 16px; backgro=
und-color: rgb(238, 238, 238); color: rgb(102, 102, 102);">-</span><span st=
yle=3D"font-family: 'Andale Mono', 'Courier New', Courier, monospace; line-=
height: 16px; background-color: rgb(238, 238, 238); color: rgb(102, 102, 10=
2);">1</span><span style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono'=
, 'Courier New', Courier, monospace; line-height: 16px; background-color: r=
gb(238, 238, 238);">)</span><br style=3D"color: rgb(0, 0, 0); font-family: =
'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px; backgr=
ound-color: rgb(238, 238, 238);"><tt style=3D"font-family: 'Andale Mono', '=
Courier New', Courier, monospace; color: rgb(0, 0, 0); line-height: 16px; b=
ackground-color: rgb(238, 238, 238);"><span style=3D"white-space: pre-wrap;=
"> </span></tt><span style=3D"font-family: 'Andale Mono', 'Courier N=
ew', Courier, monospace; line-height: 16px; background-color: rgb(238, 238,=
238); color: rgb(0, 128, 0);"><strong>return</strong></span><span style=3D=
"color: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, m=
onospace; line-height: 16px; background-color: rgb(238, 238, 238);"> <=
/span><span style=3D"font-family: 'Andale Mono', 'Courier New', Courier, mo=
nospace; line-height: 16px; background-color: rgb(238, 238, 238); color: rg=
b(0, 128, 0);">NULL</span><span style=3D"color: rgb(0, 0, 0); font-family: =
'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px; backgr=
ound-color: rgb(238, 238, 238);">;</span><br style=3D"color: rgb(0, 0, 0); =
font-family: 'Andale Mono', 'Courier New', Courier, monospace; line-height:=
16px; background-color: rgb(238, 238, 238);"><tt style=3D"font-family: 'An=
dale Mono', 'Courier New', Courier, monospace; color: rgb(0, 0, 0); line-he=
ight: 16px; background-color: rgb(238, 238, 238);"><span style=3D"white-spa=
ce: pre-wrap;"> </span></tt><span style=3D"font-family: 'Andale Mono', '=
Courier New', Courier, monospace; line-height: 16px; background-color: rgb(=
238, 238, 238); color: rgb(0, 128, 0);"><strong>if</strong></span><span sty=
le=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Couri=
er, monospace; line-height: 16px; background-color: rgb(238, 238, 238);">&n=
bsp;(size </span><span style=3D"font-family: 'Andale Mono', 'Courier N=
ew', Courier, monospace; line-height: 16px; background-color: rgb(238, 238,=
238); color: rgb(102, 102, 102);">></span><span style=3D"color: rgb(0, =
0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monospace; line-=
height: 16px; background-color: rgb(238, 238, 238);"> </span><span sty=
le=3D"font-family: 'Andale Mono', 'Courier New', Courier, monospace; line-h=
eight: 16px; background-color: rgb(238, 238, 238); color: rgb(102, 102, 102=
);">255</span><span style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono=
', 'Courier New', Courier, monospace; line-height: 16px; background-color: =
rgb(238, 238, 238);">)</span><br style=3D"color: rgb(0, 0, 0); font-family:=
'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px; backg=
round-color: rgb(238, 238, 238);"><tt style=3D"font-family: 'Andale Mono', =
'Courier New', Courier, monospace; color: rgb(0, 0, 0); line-height: 16px; =
background-color: rgb(238, 238, 238);"><span style=3D"white-space: pre-wrap=
;"> </span></tt><span style=3D"color: rgb(0, 0, 0); font-family: 'An=
dale Mono', 'Courier New', Courier, monospace; line-height: 16px; backgroun=
d-color: rgb(238, 238, 238);">size </span><span style=3D"font-family: =
'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px; backgr=
ound-color: rgb(238, 238, 238); color: rgb(102, 102, 102);">=3D</span><span=
style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', C=
ourier, monospace; line-height: 16px; background-color: rgb(238, 238, 238);=
"> </span><span style=3D"font-family: 'Andale Mono', 'Courier New', Co=
urier, monospace; line-height: 16px; background-color: rgb(238, 238, 238); =
color: rgb(102, 102, 102);">255</span><span style=3D"color: rgb(0, 0, 0); f=
ont-family: 'Andale Mono', 'Courier New', Courier, monospace; line-height: =
16px; background-color: rgb(238, 238, 238);">;</span><br style=3D"color: rg=
b(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monospace; =
line-height: 16px; background-color: rgb(238, 238, 238);"><tt style=3D"font=
-family: 'Andale Mono', 'Courier New', Courier, monospace; color: rgb(0, 0,=
0); line-height: 16px; background-color: rgb(238, 238, 238);"><span style=
=3D"white-space: pre-wrap;"> </span></tt><span style=3D"color: rgb(0, 0,=
0); font-family: 'Andale Mono', 'Courier New', Courier, monospace; line-he=
ight: 16px; background-color: rgb(238, 238, 238);">buffer </span><span=
style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', C=
ourier, monospace; line-height: 16px; background-color: rgb(238, 238, 238);=
white-space: pre-wrap;">[</span><span style=3D"color: rgb(0, 0, 0); font-f=
amily: 'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px;=
background-color: rgb(238, 238, 238);">size</span><span style=3D"color: rg=
b(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monospace; =
line-height: 16px; background-color: rgb(238, 238, 238); white-space: pre-w=
rap;">]</span><span style=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono=
', 'Courier New', Courier, monospace; line-height: 16px; background-color: =
rgb(238, 238, 238);"> </span><span style=3D"font-family: 'Andale Mono'=
, 'Courier New', Courier, monospace; line-height: 16px; background-color: r=
gb(238, 238, 238); color: rgb(102, 102, 102);">=3D</span><span style=3D"col=
or: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier, monos=
pace; line-height: 16px; background-color: rgb(238, 238, 238);"> </spa=
n><span style=3D"font-family: 'Andale Mono', 'Courier New', Courier, monosp=
ace; line-height: 16px; background-color: rgb(238, 238, 238); color: rgb(10=
2, 102, 102);">0</span><span style=3D"color: rgb(0, 0, 0); font-family: 'An=
dale Mono', 'Courier New', Courier, monospace; line-height: 16px; backgroun=
d-color: rgb(238, 238, 238);">;</span><br style=3D"color: rgb(0, 0, 0); fon=
t-family: 'Andale Mono', 'Courier New', Courier, monospace; line-height: 16=
px; background-color: rgb(238, 238, 238);"><tt style=3D"font-family: 'Andal=
e Mono', 'Courier New', Courier, monospace; color: rgb(0, 0, 0); line-heigh=
t: 16px; background-color: rgb(238, 238, 238);"><span style=3D"white-space:=
pre-wrap;"> </span></tt><span style=3D"font-family: 'Andale Mono', 'Cou=
rier New', Courier, monospace; line-height: 16px; background-color: rgb(238=
, 238, 238); color: rgb(0, 128, 0);"><strong>return</strong></span><span st=
yle=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Cour=
ier, monospace; line-height: 16px; background-color: rgb(238, 238, 238);">&=
nbsp;strdup (buffer);</span><br style=3D"color: rgb(0, 0, 0); font-family: =
'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px; backgr=
ound-color: rgb(238, 238, 238);"><span style=3D"color: rgb(0, 0, 0); font-f=
amily: 'Andale Mono', 'Courier New', Courier, monospace; line-height: 16px;=
background-color: rgb(238, 238, 238);">}</span><br></div><div><span style=
=3D"color: rgb(0, 0, 0); font-family: 'Andale Mono', 'Courier New', Courier=
, monospace; line-height: 16px; background-color: rgb(238, 238, 238);"><br>=
</span></div><div>I don't know about you, but that code makes me want to ru=
n away and hide. That's a lot of contortions (with possible off by 1 errors=
) just to deal with the fact that C forces you to use null terminated strin=
gs. The worse being that instead of just returning a pointer to the buffer =
already managed by zmq, we have to allocate a string and impose memory mana=
gement on the caller.</div><div><br></div><div>These are the kinds of conto=
rtions library implementors are forced to deal with when working with C API=
s. When string_view becomes the defacto standard for a "const reference to =
a variable length string", the library implementors will be forced to do th=
ese null and non-null conversions.<br></div><div><br></div><div>So what wou=
ld be nice is to augment the set of string functions with new functions whi=
ch take a pointer and a length. Making non-null terminated strings viable i=
n the C world. This would optimally require support from the C standard as =
well as other common standards such as POSIX. Support in the C standard wou=
ld then encourage support in other C libraries, enhancing interoperability =
all around.</div><div><br></div><div>Some examples:</div><div><br></div><di=
v>char* strdup_l(const char* s, size_t len);</div><div>FILE* fopen_l(const =
char* filename, size_t len, const char* mode, size_t mlen);</div><div>int o=
pen_l(const char* pathname, size_t len, int flags, mode_t mode);</div><div>=
DIR* opendir_l(const char* pathname, size_t len);</div><div>void* dlopen_l(=
const char* filename, size_t len, int flag);</div><div><br></div><div>-----=
-------------------------</div><div><br></div><div>What do you think C coul=
d do to help C++ and other high level languages and technologies built onto=
p of C?</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5856_298459.1391004213845--
.