Non-constant constant strings

R

Rick C. Hodgin

In C++ programming, I usually write base class initializers in a constructor
like this:
foo::foo(int arg1, char *arg2)
: base(arg1)
, otherbase(arg2)
, thirdbase(42)
{
}

Me too, though I usually indent the initializers several spaces.
The colon means the first initializer is coming, then commas signal
additional ones, and it nicely formats this way.

Yes. It does. :)

Best regards,
Rick C. Hodgin
 
R

Rick C. Hodgin

If you find your religious beliefs give you hope and encouragement,
that's fine. But please don't mix religion with programming - it
degrades both of them.

I take it on better authority than your opinion for my guidance:

Colossians 3:17 - "And whatever you do, whether in word or deed,
do it all in the name of the Lord Jesus,
giving thanks to God the Father through him."

I do what I do with RDC, Visual FreePro, and the larger Village Freedom
Project in general, entirely to give back to God of those skills that
He first gave me.

Here's another one that might interest you (just to see how backwards
this world system is from the one taught by our Creator):

1 Corinthians 10:24 - "Let no man seek his own, but every man
another's wealth."

We've been fooled by God's enemy into believe many lies. It is only God
Himself who sets us back on the path of truth. I came to be a believer
in 2004 after years of being a professed atheist. Jesus changed my life,
and I am eternally grateful.

Best regards,
Rick C. Hodgin
 
B

BartC

There are no computers anywhere in existence, be they men or machine, that
do not:

(1) Take some form of input
(2) Perform some operation on it
(3) Generate output

You could apply that to almost anything. But, so what? What are trying to
say; that you have a new concept for a computer, language, or machine that
works differently?
 
G

glen herrmannsfeldt

(snip, someone wrote)
I agree with the OP on this.
There are only 3 types of line-endings in general use: CR/LF
(Windows), LF (Linux), CR (Mac), or at least those are all I've
ever encountered.

Well, might as well add the two used commonly on IBM mainframes,
on OS/360 and descendants, which are FB (fixed length records,
usually padded with blanks, and blocked to a reasonably block size)
and VB (variable length with a length prefix, blocked together,
and with a length prefix for the block). There is a third, VBS,
(Variable Blocked Spanned) mostly used for Fortran unformatted
and equivalent for other languages, that allows for records
longer than a block.

Note also that with the above line formats that all 256 bit
combinations are allowed for characters in a line.
Relying on the C runtime to deal with any combination won't always
work. And it seems to be on Windows that it can be a problem because
Linux seems to like to inflict its LF-coded files on everyone else.
(And in Linux it's easy to be careless because binary and text
modes are the same. I've seen one file that mixed text and binary,
which presumably worked under Linux, but in Windows/C it expanded
LF to CR,LF, putting the following binary data out of step.)

The IBM mainframe C compilers in some cases do interesting things
with C ftell()/fseek(). The OS keeps track of blocks, and offset
within a block, but not byte offset into a file. If you really
need the byte offset, you have to read the file from the beginning
while counting bytes. In some cases, the return from ftell() and
the value for fseek() are something like 32768*block+offset,
such that it can actually seek to the appropriate place.

-- glen
 
R

Rick C. Hodgin

You could apply that to almost anything. But, so what? What are trying to
say; that you have a new concept for a computer, language, or machine that
works differently?

No. I'm saying that all computers are read-write by default.

I had this interesting thought the other day: If you consider the world,
the things in the world, it is only those things which are living which
alter the world in programmed ways. You don't see an area of the world
somewhere where there isn't a tree converting the elements in the ground,
air, and water, into the components of a tree. However, when the
programming of DNA is there ... it does.

Life changes things in non-mechanical ways. It's similar to computer
software. Software orchestrates things in a particular manner, taking
this, taking that, making decisions, and producing something. It's the
same with life.

Very interesting thought.

Best regards,
Rick C. Hodgin
 
J

James Kuyper

I should have said "removing", not deprecating. As I understand matters,
it should have been deprecated in at least one version of the standard
before removing it completely in some later version; instead, they
skipped a step. It should have been deprecated in C90 and removed in C99.
Without knowing more, I'd wager it's a rarely used feature that does not
have any significant impact on existing code bases should it be removed.

Not quite. gets() is used a little bit too often to call it "rare". It's
used far more often than it should be - which is never. That's because
it's possible, whenever a program calls gets(), that it may receive
input that will cause a buffer overrun. There are other standard library
functions that have that same danger, but gets() is the only one where
there's absolutely nothing that can be done from within the program
itself to either prevent that possibility, or reliably deal with it if
it does come up.

Removal of gets() from the standard library means that badly written
code which a conforming implementation of C was previously required to
translate and execute, possibly without any diagnostics, is now code
that it need not even finish translating, and for which a diagnostic is
mandatory.

That's a significant improvement, because it increases the likelihood
that the badly written code will someday be corrected. However, there's
no guarantees about that: many implementations will have a
non-conforming mode in which gets() continues to be supported, and
there's a pretty good chance that the defective code will be built in
that mode, allowing it to remain uncorrected.
 
J

James Kuyper

No. I'm saying that all computers are read-write by default.

It's possible that this is true, but only in an irrelevant sense. What C
says about string literals is that they may be written to memory at the
start of the program, but they can never be overwritten safely during
the rest of that program's lifetime. There are real-world systems which
provide hardware support for precisely that concept, and operating
systems that make use of that hardware support. Such systems either
don't count as computers by your definition, or they fail to support
your denial of the legitimacy of write-once objects. I'm not sure which,
since the meaning of input/processing/output in your definition of
computers is a little vague.
 
I

Ian Collins

Rick said:
Those are entirely separate issues. They are completely outside of my
control. The goals I have in my application are to be minimally wasteful.
I even use 1-byte alignment on my compiler settings, sacrificing a little
speed for some extra packing. :)

The goals I have in my application are to be minimally wasteful, so I
correctly align things to avoid wasting cycles....
 
I

Ian Collins

Rick said:
You can only omit them from certain levels of diagrams, as when working in
pure theory. Any real-world model would have to consider them because they
do exist.

Nonsense. Gate level abstractions are used everywhere except for the
design of the gates them selves.
 
K

Keith Thompson

James Kuyper said:
On 01/22/2014 11:14 AM, Rick C. Hodgin wrote:
...

C has already changed significantly several times since first
standardized, most notably in 1995, 1999, and 2011. Why do you expect it
to suddenly stop changing? The C committee has made a commitment to
avoid making changes that break backwards compatibility, which means
that some bad decisions from the past are unlikely to ever be corrected,
but even that's not certain. Such changes are only to be "avoided", not
"prohibited". For instance, in C2011 they did finally get around to
deprecating gets(), though they took a couple of decades longer than
they should have.

They didn't merely deprecate gets(); that would mean declaring that its
use is discouraged and it may be removed in a future standard. They
removed it completely (without going through an initial step of marking
it as obsolescent).
 
R

Rick C. Hodgin

I was able to get it working. I wound up using a combination of GCC's
g++ and Microsoft's Visual C++ compiler. COFF object file output in
GCC was the key.

Here's are the steps for a sample build on a Windows 7 machine 64-bit:

(1) Install MinGW on Windows with GCC and bases.
(2) Create the two source files below.
(3) Launch a command prompt that has the path for visual studio tools.
(4) Execute these steps:
(a) C:\>PATH=%PATH%;c:\mingw\bin\
(b) C:\>g++ -c -gcoff list.cpp -o list.obj
(c) C:\>cl /c main.cpp
(d) C:\>link main.obj list.obj /OUT:main.exe
(e) C:\>main
!ne
!wo
!three


=========list.cpp========
#define RW(x) (char []) { x }

extern "C"
{

char* list[] =
{
RW("one"),
RW("two"),
RW("three")
};

}
===========END===========


=========main.cpp========
#include <stdlib.h>
#include <stdio.h>

extern "C"
{
extern char* list[];
}

int main(int argc, char* argv[])
{
for (int i = 0; list; i++)
{
list[0] = '!'; // Prove it's read-write
puts(list); // Show it
}
}
===========END===========

g++ and cl working hand-in-hand. :) Gotta love it. :)

Best regards,
Rick C. Hodgin
 
R

Rick C. Hodgin

Note: I was able to get it working using gcc and cl on list.c and main.c
as well. It doesn't only work in C++, but that was my original
target toolset, just with "mostly C" code. :)

Best regards,
Rick C. Hodgin
 
G

glen herrmannsfeldt

Keith Thompson said:
(snip)

They didn't merely deprecate gets(); that would mean declaring that its
use is discouraged and it may be removed in a future standard. They
removed it completely (without going through an initial step of marking
it as obsolescent).

But did they go as far as requiring it not to be in the library?

-- glen
 
K

Kaz Kylheku

That runs counter to almost all modern thinking in language design -
visibility and access should, by default, be restricted as much as
possible.

Rick doesn't "get" that the low levels are made irrelevant by the language.

You can complete a project in a modern language without ever having to refer
to machine registers or stacks, and in much of the code (in some cases all)
you can avoid mutating variables.

The machine may be a Von Neumann stored-programc omputer pushing word-size
quantities through a meat-grinder like CPU, but at no point in the cycle of
that program do you have to think about this.

(The exception to this occurs when something goes so drastically wrong, that
you have to debug below the language level. Perhaps the run-time has a bug, or
else the language has holes in it which allow behaviors outside of its "box",
which, if they go wrong, can only be explained/root-caused by going to the
lower levels.)

The idea that because machine/assembly language is such and such, or the
computer architecture is in a certain way, all computer *programming* is such
and such, is laughably naive.

Languages and their environments completely change the face of the computer to
a different personality, and reshape (perhaps from the ground up) the mental
model used for programming.

Those who don't understand this are condemned to be the proverbial programmers
who "code Fortran in any language".

This is what we are dealing with here (though perhaps substitute "x86 assembly"
for "Fortran").

Fact is that a code generation task based on substituting variable pieces
into otherwise static templates can be solved without mutating variables.

(It cannot be solved without stacks being walked, or registers being loaded,
but that is irrelevant since none of these concepts appear in the structure of
the solution expressed in the high level language.)

Moreover, any solution for that type of problem which involves mutating
the templates themselves is decades behind the state of the art.

I'd not give it full marks if it came in as a homework solution from a second
year CS student. First year, maybe.
 
K

Keith Thompson

glen herrmannsfeldt said:
But did they go as far as requiring it not to be in the library?

Yes. That is, it may longer be declared in <stdio.h>, and a strictly
conforming program may define its own function named "gets".

Of course a non-standard library may provide a gets() function; in that
respect, it's no different from a foo() function.
 
K

Keith Thompson

Keith Thompson said:
Yes. That is, it may longer be declared in <stdio.h>, and a strictly
conforming program may define its own function named "gets".

Sorry, I accidentally a word there.

gets() may *no* longer be declared in <stdio.h> (at least not in such a
way that it interferes with any strictly conforming program that defines
something called "gets" itself). As far as C11 is concerned, "gets" is
just another identifier with no special significance.
 
R

Rick C. Hodgin

Rick doesn't "get" that the low levels are made irrelevant by the language.

You can complete a project in a modern language without ever having to refer
to machine registers or stacks, and in much of the code (in some cases all)
you can avoid mutating variables.

There are high level people, Kaz, and low-level people. Those languages
you love so well at the high level were written by people who toil down
in the low level.

Be proud of the fact that you are a good high-level developer, Kaz, that you
know all the tricks of the language and can whip code as rapidly as anyone
else, and leave the low-level development to those who are interested in
development at those lower levels. By doing this you'll always have those
people to thank for providing you with the ability to do your work.

Best regards,
Rick C. Hodgin
 
K

Kaz Kylheku

But did they go as far as requiring it not to be in the library?

Obviously, a strictly conforming C program can now use gets as an external
name, since no such name is reserved any more. Its behavior is undefined
if it declares such a function, doesn't define it and calls it.

Implementations that provide gets for programs in older C dialects have
to somehow conceal gets to allow the program to use the identifier.

The strongest way in which a standard can "banish" something is to make it
a violation that requires a diagnostic. Yet, a diagnostic does not amount to
that construct being "removed". C implementations provide extensions even
based on syntax errors. In a conforming mode, they emit the required
diagnostic for the odd syntax, and then proceed to translate it.

That is the extent to which gets could, in principle, be required to be
removed: a diagnostic could be required if such an external name is referenced,
and that diagnostic would not amount to a failure to translate and execute the
program (whose behavior would then be undefined).

Some implementations voluntarily provide such a diagnostic, notably the
GNU C Library with its link-time warning.
 
K

Kaz Kylheku

Note: I was able to get it working using gcc and cl on list.c and main.c
as well. It doesn't only work in C++, but that was my original
target toolset, just with "mostly C" code. :)

Using multiple compilers and dialects to build one program, for the sake of
some issue of syntactic sugar in the source code (and saving a few bytes while
the program is running) is ... in the territory of Mel, the Real Programmer.

'"Even the initializer is optimized", he said proudly'

Yes, you optimized the initializers, just like Mel.

References:

http://en.wikipedia.org/wiki/The_Story_of_Mel
http://www.cs.utah.edu/~elb/folklore/mel.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,206
Latest member
Zenden

Latest Threads

Top