On Mon, Jun 19, 2017 at 4:25 PM, Frank Swarbrick < frank.swarbr...@outlook.com> wrote:
> I know there are at least a few C developers here, so I was wondering if > you could answer a question. Is the following valid C? (I'm not asking if > one should actually do it; only if its valid at all.) > char *get_static_string(void) { > static char str[81] = "This is a statically allocated C string"; > return str; > } > > > printf("%s", get_static_string()); > > > I don't have a C compiler available at work else I'd try it myself. > > Frank > > You have gotten some good answers. So I will just interject a bit of, perhaps off center, comment. Your code, as written compiles just fine. But it is basically very dangerous. The reason is that you are returning a pointer which could be used to overwrite storage. This is also known as "a bad thing" and is basically an attack vector by malicious code. I don't know the actual intent of your question. But I would suggest using the #pragma string(readonly) in your example. E.g. compile "get_static_string" in its own compilation unit (i.e. by itself) #pragma strings(readonly) const char *get_static_string() { const static char[] = "This is a statically allocated C string"; // let the compiler figure out the length; return str; } I can hear you saying: "But, really, I need up be able to update this string on occasion." If so, then I would greatly suggest that you create a "compilation unit" (single file containing source which is compiled independently ) such as: # file static_string.c #if ! defined(MAXSTRLEN) #define MAXSTRLEN 100 #endif #include <string.h> static char str[MAXSTRLEN]; const char *get_static_string(void) { return str; } int set_static_string(char *set_to_value) { int len_to_set = strnlen(set_to_value,MAXSTRLEN); if (len_to_set >= MAXSTRLEN) // string too long! return 1; // tell caller NO GO! memcpy(str,set_to_value,len_to_set); // fast copy return 0; } Since the variable "str" is defined as "static" and outside of any function definition, it is "global" to the "compilation unit", but is not known outside of it (i.e. it is not an external name). You compile the above to "object" code. You may be able to bind it into a LOADLIB, but I think you'll get some "external reference not found" type messages for "main". Anyway, the above could be similar to: # file use_static_string.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> const char *get_static_string(void); int set_static_string(char *); int main(int argc, char *argv[]){ char set_to_1[]="Set to this value"; char set_to_2[]="Set to another value"; const char *return_static_string; int retRC; retRC=set_static_string(set_to_1); if (retRC != 0) { printf("retRC=%d\n",retRC); exit(1); } return_static_string=get_static_string(); printf("%s\n",return_static_string); retRC=set_static_string(set_to_2); if (retRC != 0) { printf("retRC=%d\n",retRC); exit(1); } return_static_string=get_static_string(); printf("%s\n",return_static_string); } Please note that I did test the above, but not on z/OS. I did it on Linux/Intel at home. But it is fairly generic and so should work on z/OS with xlc as well. Also note the use of MAXSTRLEN. This is really a "preprocessor" value. Why did I use it as I did? Because if 100 is not correct, you can change the MAXSTRLEN value on the compile with the -D compile option. I don't remember how to do this with JCL, but on a UNIX shell prompt, you can do something like: xlc -c -DMAXSTRLEN=256 -o static_string.o static_string.c # MAX string length is 256 (255 chars + NUL ending) # compile, don't link xlc -o use_static_string use_static_string.c static_string.o # compile and link object from above -- Veni, Vidi, VISA: I came, I saw, I did a little shopping. Maranatha! <>< John McKown ---------------------------------------------------------------------- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN