Sunday, June 28, 2020

Digest for comp.lang.c++@googlegroups.com - 18 updates in 4 topics

Ian Collins <ian-news@hotmail.com>: Jun 28 01:26PM +1200

On 28/06/2020 11:20, Keith Thompson wrote:
> result of array-to-pointer conversion) or of some class type (which
> includes struct or union type) with an appropriately overloaded
> operator[].
 
The biggest difference with C++ is that through operator overloading you
can copy from and assign to full elements (such as whole rows and
columns) of a multidimensional array. std::array is a very handy tool
to have.
 
--
Ian.
jacobnavia <jacob@jacob.remcomp.fr>: Jun 28 09:33AM +0200

Le 27/06/2020 à 20:32, Bonita Montero a écrit :
 
> If you are not writing your own complex-class for educational purposes:
> you can #include <complex> and thereby have a full blown complex-class
> with all appropriate operators.
 
Yes, lcc-win supports the standard complex numbers. That was an
exemple of operator overloading though, I could have choosen anything
else but that was the first that came to mind. Maybe not a good exemple
David Brown <david.brown@hesbynett.no>: Jun 28 10:14AM +0200

On 28/06/2020 03:26, Ian Collins wrote:
> can copy from and assign to full elements (such as whole rows and
> columns) of a multidimensional array.  std::array is a very handy tool
> to have.
 
Operator overloading is just one part of the mechanics that allow that.
I wonder if and how lcc can support something like that, without
(AFAIUI) classes, overloads of normal functions, constructors and
destructors?
jacobnavia <jacob@jacob.remcomp.fr>: Jun 28 11:47AM +0200

Le 28/06/2020 à 10:14, David Brown a écrit :
 
> I wonder if and how lcc can support something like that, without
> (AFAIUI) classes, overloads of normal functions, constructors and
> destructors?
 
1) No classes. Just structures and unions. No inheritance and no object
oriented programming support. You can (of course) do object oriented
programming in C as many frameworks available will prove.
 
2) Overloads of normal functions are also supported
 
int overloaded fn(int a); // 1
int overloaded fn(char *b); // 2
 
int main(void) {
fn("foo"); // 2
fn(45); // 1
}
 
3) No constructors nor destructors. This is C and you do it yourself.
 
Using operator overloading lcc-win supports many types of numbers:
 
bignums
big floats (448 bits precision)
 
You can define your own addition, etc for introducing clapped addition,
for instance.
 
Key is: Do not follow the C++ path. KEEP IT SIMPLE! but no simpler than
what is required. Operator overloading is very useful. It allows us to
use a known notation.
 
Noteworthy is that lcc-win supports operator [ ] reading from an array
and operator [ ] = assigning to an array element. This allows to
implement read only arrays
Ike Naar <ike@faeroes.freeshell.org>: Jun 28 11:06AM

> {
> cmplx a,b={2,3},c={4,5};
> c = a+b;
 
Did you mean
 
a = b+c;
?
Bart <bc@freeuk.com>: Jun 28 12:16PM +0100

On 28/06/2020 09:14, David Brown wrote:
> I wonder if and how lcc can support something like that, without
> (AFAIUI) classes, overloads of normal functions, constructors and
> destructors?
 
I'm about to implement operator overloading (not in a C-related language).
 
It doesn't need any such features, only a compiler directive to
associate a regular function with an operator and a set of operand
types. Suppose S and T are two user types on which you want to use
binary "+", then, using pseudo-C syntax:
 
S addS(S a, S b) {S c; ....; return c;}
 
T addT(T a, T b) {T c; ....; return c;}
 
#pragma setoverload "+"(S,S) addS
#pragma setoverload "+"(T,T) addT
 
S x,y,z;
z = x+y; // tranformed to z = addS(x,y)
 
If constructors and destructors are needed, then they will be needed
regardless of operator overloading. This is just so you can write x+y+z
instead of addS(x,addS(y,z)).
jacobnavia <jacob@jacob.remcomp.fr>: Jun 28 02:48PM +0200

Le 28/06/2020 à 13:06, Ike Naar a écrit :
 
> Did you mean
 
> a = b+c;
> ?
 
yes, just a stupid typo
 
thanks
Juha Nieminen <nospam@thanks.invalid>: Jun 28 03:42PM

> be used - backwards compatibility is a bugger when you have to keep
> supporting language design mistakes. Personally, I think /all/ use of
> the comma operator should have been deprecated.
 
The advantage of my proposal above is that it would be fully
backwards-compatible with existing code, and there would be zero
need to deprecate or change anything in the current language
(with the exception of, rather obviously, that now operator[]()
can take more than one parameter, which is not a backwards
compatibility breaking change nor needs any deprecation of
anything.)
 
Of course not being a C++ standard expert or a compiler developer,
I don't know if it could perhaps cause some kind of ambiguity in
some situations, where the compiler cannot know if "obj[1][2]"
refers to one thing or another.
 
It could certainly be ostensibly problematic if the class has
an operator[]() taking one parameter and another taking two,
as the compiler wouldn't know which one the "obj[1][2]" should call.
jacobnavia <jacob@jacob.remcomp.fr>: Jun 28 10:32PM +0200

Le 27/06/2020 à 17:36, Juha Nieminen a écrit :
> std::cout << "[" << i1 << "][" << i2 << "]\n";
> }
> };
 
I have been studying your proposal, and I have some questions:
 
1) In this example you are overloading the indexing operator for an
array of a specific size, that you enter in your overloading definition.
 
(If I understood correctly of course)
 
Now, in my implementation I was thinking about this operator for a
general object of a certain rank. Instead of specific table sizes you
would just give an integer RANK of the array being overloaded.
 
The advantages of this, is that you overload the indexing operator for
ALL arrays of a certain number of dimensions (its rank) instead of
having to overload each array of different sizes.
 
Practically you would want to overload all tables, and not only tables
of 2 by 5 and write another operator for tables of 2 by 7, say.
 
I thought that in overloading the operator you would overload by rank
like this
 
operator [2](T basetype, int idx1, int idx2) { ... }
 
Of course in C++ you don't pass the first argument (implicit this)
and the operator would be written
 
operator[2](int idx1,int idx2);
 
That would mean that ALL tables (rank 2) of that class would be
overloaded with the definition, not only tables of a specific size.
 
What do you think?
 
jacob
ram@zedat.fu-berlin.de (Stefan Ram): Jun 28 06:16PM

>Yes, in C we use the exact same syntax for a pointer to a single object,
>and a pointer into an array of objects, and it is the job of the
>programmer to keep this distinction clear (if he needs to).
 
The importance of this distinction has perhaps been somewhat
overemphasized in some recent posts to this newsgroup. When
an expression has type "T*" and has a valid non-zero value at
runtime, then it points to an object of type T. This is still
true when this object happens to be some kind of subobject.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 27 04:36PM -0700

Bart <bc@freeuk.com> writes:
[...]
> char* type, this could point to one character (a 0D array), or the
> first of a sequence (a 1D array of char or a zero-terminated
> string). With the possibilities with each extra * growing.
 
A value of type char* points to a single object of type char. [*]
 
That object may or may not be the initial element of an array object.
 
Please don't try to make it sound more complicated than it really is.
 
[*] Or it may be a null pointer, or an invalid pointer, or a pointer
just past the end of an array object.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Bart <bc@freeuk.com>: Jun 28 01:44AM +0100

On 28/06/2020 00:36, Keith Thompson wrote:
 
> Please don't try to make it sound more complicated than it really is.
 
> [*] Or it may be a null pointer, or an invalid pointer, or a pointer
> just past the end of an array object.
 
/Could/ a char* be used to point to the first of several or many
characters? Such as the first argument here:
 
fopen("hello.c","w")
 
If so then my point stands. I was replying to somebody who'd posted
diagrams, which need not correspond to the intended uses of those types.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 27 06:09PM -0700


> /Could/ a char* be used to point to the first of several or many
> characters? Such as the first argument here:
 
> fopen("hello.c","w")
 
Of course it could. That's what I said.
 
> If so then my point stands.
 
So does mine.
 
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
David Brown <david.brown@hesbynett.no>: Jun 28 10:11AM +0200

On 28/06/2020 02:44, Bart wrote:
 
>     fopen("hello.c","w")
 
> If so then my point stands. I was replying to somebody who'd posted
> diagrams, which need not correspond to the intended uses of those types.
 
If I tell you "there's a letter A written on a piece of paper", then
that letter could be stand-alone, it could be part of a word, part of a
sentence, part of a Shakespeare play or Fermat's mythical proof of his
theorem. But it is pointless to try to consider all the possibilities.
 
A valid char* points to an object of type char. No more, no less. Like
any object in C, that may or may not be part of an array.
 
You have worked long and hard through the years to make yourself as
confused as possible about C pointers, and to find new ways to hate the
language. Please don't spread that confusion to others. When someone
asks fundamental questions about C in this newsgroup, it is an
opportunity for you to shut up and listen - maybe you'll learn
something, or gain some insight. Spreading FUD is not helpful to
anyone, and just annoys people.
Bart <bc@freeuk.com>: Jun 28 11:05AM +0100

On 28/06/2020 09:11, David Brown wrote:
> opportunity for you to shut up and listen - maybe you'll learn
> something, or gain some insight. Spreading FUD is not helpful to
> anyone, and just annoys people.
 
The diagrams posted by Stefan Ram (setting aside the error) could have
been misleading as to the intentions of the code.
 
Yes, in any language with incremental pointers, P /could/ point to 1 or
N objects. But only in C is that used as a fundamental idiom.
 
So with char** pp, in C there is no problem in accessing a terminal char
object as either:
 
**pp // as per the diagram
pp[i][j] // rather differently to the diagram
*pp[i]; // differently yet again
(*pp)[i]; // and again
 
These require 4 different diagrams.
 
So, you want to hide all this from the OP? OK.
 
There further differences when the target you want to deal with is a
C-style zero-terminated string implemented char* rather than a char:
 
*pp; // pp points to a single char* string
pp[i]; // When pp is an array of char* in C style
Richard Damon <Richard@Damon-Family.org>: Jun 28 07:47AM -0400

On 6/28/20 6:05 AM, Bart wrote:
> C-style zero-terminated string implemented char* rather than a char:
 
>     *pp;                // pp points to a single char* string
>     pp[i];              // When pp is an array of char* in C style
 
Actually, the digrams given implied that each pointer was to a single
object and not into an array (since the target of the pointer was a
single box.
 
In fact, since we were also given the program that it represents, we
know that fact.
 
Yes, in C we use the exact same syntax for a pointer to a single object,
and a pointer into an array of objects, and it is the job of the
programmer to keep this distinction clear (if he needs to). This is all
in line with the goal of the language which was designed to be a light
weight language capable of producing very efficient code, based on a
trust that the programmer will 'follow the rules' and do things right.
Bart <bc@freeuk.com>: Jun 28 04:38PM +0100

On 28/06/2020 12:47, Richard Damon wrote:
> in line with the goal of the language which was designed to be a light
> weight language capable of producing very efficient code, based on a
> trust that the programmer will 'follow the rules' and do things right.
 
C also has the syntax to do it properly; suppose S is a typedef (eg. for
char*):
 
S* A;
 
This is the idiom used when A is a dynamically allocated array of A. It
could also be intended to point to a single A (maybe in the middle of a
struct). Access to elements is via A[i].
 
The proper way is:
 
S (*A)[];
 
A is not a pointer to array of S, not a pointer S. Access though is via
(*A)[i]. But nobody uses this (except me during C code generation, but
even I don't bother usually because of the fiddly syntax).
 
This doesn't fix everything though as, when bounds are present, this can
be still be indexed, without error, as A[i] as well as (*A)[i]. The
former expression is an access to the (i-1)th array, which may or may
not exist.
woodbrian77@gmail.com: Jun 27 05:39PM -0700

> project if we use my software as part of the project.
> More info here: http://webEbenezer.net/about.html
> .
 
Some people have left C++ for other languages.
Not me; I'm looking for some C++ users.
 

Brian
Ebenezer Enterprises - Enjoying programming again.
https://webEbenezer.net
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: