Why isn't my array working?

Started by
18 comments, last by King Mir 11 years, 2 months ago

I am using K & R to learn C and I was just copying what they did. There was a typo in the book, and I didn't know it was bad to use macros.

Advertisement

Rather than using #define to define constants it's better to just make constants:


const size_t SIZE = 10;
This gives you type control and avoids macro expansion problems like the one you encountered.

Using #define is almost the same as using your a text editor's 'find-and-replace' function. There are some cases where it's useful, but usually it causes more problems than it solves.

Actually, I don't think this is true in C. I couldn't get this to work:

const int N = 10;

struct S {
  int i[N];
};

I had forgotten about this additional problem. Yeah, that's the other reason to use a macro. Constant variables are not constant expressions.

I am using K & R to learn C and I was just copying what they did. There was a typo in the book, and I didn't know it was bad to use macros.

It's not for this. Just don't do it in C++.

K & R is a very old book though. There should be better, more modern, books out there. In particular, it's bad practice (and may be against C99, I'm not sure) to use implicit return int like you do. You should explicitly write "int main".

I am using K & R to learn C and I was just copying what they did. There was a typo in the book, and I didn't know it was bad to use macros.

It's not bad to use macros per se. But if you do then you need to understand the consequences of using them and give yourself some strict guidelines in doing so. In C programming, they can be quite useful (extremely so, in some cases). The flip side is that it is easy to create macros that do not behave the way you expect them to. In C++, there are better, less error-prone alternatives, hence macros are frowned upon in the general case. But even in C they should be used with care. For simple constant values like SIZE, they are perfectly safe. When I program C, I prefer macros for that situation unless I need several related constants, in which case I'd use an enum, You just need to keep in mind any issues that may arise from the data type being used (i.e. signed vs unsigned, integer vs floating point), but that's something you need to be aware of with any variable.

Álvaro, on 11 Feb 2013 - 13:49, said:
Actually, I don't think this is true in C. I couldn't get this to work:

const int N = 10;

struct S {
  int i[N];
};

That would definitely be a good case to use them. (I didn't say never to use them.) I think you can still use const values in stack arrays though. They cause so many problems so easily I just really think it's best to avoid them wherever possible.

King Mir, on 11 Feb 2013 - 13:29, said:
The problem with const size_t is that a global variable defined like that is addressable, and must be generated in the object file. #define, for it's faults, does not have this problem. Therefore I consider a #defined macro to be the preferred general purpose way to declare constants in C.

Why is this a problem? I don't follow.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.


Álvaro, on 11 Feb 2013 - 13:49, said:
Actually, I don't think this is true in C. I couldn't get this to work:

const int N = 10;

struct S {
  int i[N];
};


That would definitely be a good case to use them. (I didn't say never to use them.) I think you can still use const values in stack arrays though. [...]


Sort of. C99 has variable-length arrays, which is why it will work if you use a `const' variable as the size of an array on the stack.

Álvaro, on 12 Feb 2013 - 06:26, said:
Sort of. C99 has variable-length arrays, which is why it will work if you use a `const' variable as the size of an array on the stack.

!

I did not know this thing.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

.
King Mir, on 11 Feb 2013 - 13:29, said:
The problem with const size_t is that a global variable defined like that is addressable, and must be generated in the object file. #define, for it's faults, does not have this problem. Therefore I consider a #defined macro to be the preferred general purpose way to declare constants in C.

Why is this a problem? I don't follow.

Álvaro pointed out the bigger issue, which is that constant variables are not compile time constants from a language perspective, and so cannot be used in array sizes generally. I was pointing out that the compiler is not required to promote them to compile time constants.

King Mir, on 12 Feb 2013 - 16:59, said:
Álvaro pointed out the bigger issue, which is that constant variables are not compile time constants from a language perspective, and so cannot be used in array sizes generally. I was pointing out that the compiler is not required to promote them to compile time constants.

Ah. I get you. Are there any plans to update C any more? Seems like something that could easily be standardized.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

King Mir, on 12 Feb 2013 - 16:59, said:
Álvaro pointed out the bigger issue, which is that constant variables are not compile time constants from a language perspective, and so cannot be used in array sizes generally. I was pointing out that the compiler is not required to promote them to compile time constants.

Ah. I get you. Are there any plans to update C any more? Seems like something that could easily be standardized.

The C working group is definitely alive and updating, and C11 recently came out, but, as far as I know, changing the nature of const to match C++ is not something anyone is pushing for. The latest proposals can be found here http://www.open-std.org/jtc1/sc22/wg14/www/docs/PostPortland2012.htm

But there's not as much energy for improving C as there is for C++, and even C99 adoption has been poor. Notably Visual studio does not and does not plan to support C99.

This topic is closed to new replies.

Advertisement