Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
FlapYoJacks
Feb 12, 2009

Morham posted:

Ok just to put this one to bed, I got it working, thank you all for your help. I am still not 100% sure I get it but it is at least there for me to look at and decipher in my own time.

code:
char again;

do
{
   printf("Would you like to try again? (y/n): ");
   scanf("%s", &again);
}
while (!(again == 'y' || again == 'n'));
Like ratbert90 said the computer would see '[y][\n]' however the character variable 'again' is only capable of holding one character (unlike if I made it a char*), so it takes the 'y' and ignores the '\n'. I am assuming this is the correct interpretation and why this works.

Interestingly if I set it to take a character ('%c') it prints the 'would you like to try again (y/n): ' line twice before stopping to ask for input.

Coding is weird.

You are asking for input before all this correct? The \n is still in the buffer from the previous guess, which is why it asks twice, because it sees something in the stdin buffer and it isn't y or n.

If this is for class I really suggest the book "C Primer Plus". Its huge and incredibly well written for the basics of C and how things work. Its the book I used to teach myself C and then I went to college. :v:

Adbot
ADBOT LOVES YOU

BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER

ether posted:

Bad design or not, using real world visible data as keys (which might be subject to change now or in the future) complicates your schema on other ways. StudentID is not at all a fixed number (or a number at all) in the software we created used for tracking close to a million students in the Netherlands. We made the same assumption as well in the past and have had to rework quite a bit to allow changing studentid's. The solution now is an ugly hack because the schema is like that.

I personally wouldn't use visible data as a key ever as rule of thumb.

That, makes a lot of sense. Especially because of the table that would use visible ID's, the Course table (lists all available courses), could run into the same problem if either a) it's major is fractured or combined with another or b) the course number gets changed. From this, does it stand to reason that I should I prepare a field (or maybe even a mapping table) for "old," visible values? Especially when used as part of cataloging information. (And yes, this is different getting beyond the scope of a personal project whose cheif purpose is to teach me SQL and demonstrate it.)

For example, consider a college uses a [Maj code] #### format for their course numbering. If the Computer Science department switches from CS to COMP for their major code, should the Computer Science record remember that the old code was "CS" for legacy purposes? As in knowing that COMP0401 is the same as CS0401.

EDI: I'm also dropping Qt from the project. It's too much to throw in there at one go for a minor improvement. Plus, the SQL stuff that's built in doesn't really jive with what I had previously designed based on SQLite's library. Not that I'm getting SQLite to compile on VS 2010 express...

BirdOfPlay fucked around with this message at 21:42 on May 18, 2013

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

BirdOfPlay posted:

That, makes a lot of sense. Especially because of the table that would use visible ID's, the Course table (lists all available courses), could run into the same problem if either a) it's major is fractured or combined with another or b) the course number gets changed. From this, does it stand to reason that I should I prepare a field (or maybe even a mapping table) for "old," visible values? Especially when used as part of cataloging information. (And yes, this is different getting beyond the scope of a personal project whose cheif purpose is to teach me SQL and demonstrate it.)

For example, consider a college uses a [Maj code] #### format for their course numbering. If the Computer Science department switches from CS to COMP for their major code, should the Computer Science record remember that the old code was "CS" for legacy purposes? As in knowing that COMP0401 is the same as CS0401.

That sounds like a good idea. What you'd probably do is have a table that maps user-visible course name and year* to the underlying synthetic key that you're using as a course identifier. If they change the course identifier for a course, then you add another entry to that table mapping the new course identifier to the same synthetic course id.

* Universities like to do things like swap course numbers around annoyingly often, in my experience

klosterdev
Oct 10, 2006

Na na na na na na na na Batman!
I'm writing a simple program for work to wake on lan a bunch of computers in an internet cafe in the morning. It's set to launch an .exe in the command line, then enter mac addresses one at a time into the .exe until everything has been hit. At the moment I'm just shoving the MAC addresses into the source code, but that's sloppy and I want to insert it into a text file and have my program read from it, line by line, and insert it into the
code:
result=system("C:/Test/mc-wol.exe INSERT MAC HERE");
line. Is there an easy way to do this for somebody who knows very little C?

code:
#include<stdlib.h>
#include<stdio.h>

/* main() returns int, not void. */
int main( void ) 
{
int result ;
  result=system("C:/Test/mc-wol.exe 00:14:22:dd:a0:3c"); //computer 1
  result=system("C:/Test/mc-wol.exe dd:dd:dd:dd:dd:dd");  //computer 2
  result=system("C:/Test/mc-wol.exe aa:aa:aa:aa:aa:aa");  //computer 3
  system ("PAUSE" );
  return 0;
}

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

klosterdev posted:

I'm writing a simple program for work to wake on lan a bunch of computers in an internet cafe in the morning. It's set to launch an .exe in the command line, then enter mac addresses one at a time into the .exe until everything has been hit. At the moment I'm just shoving the MAC addresses into the source code, but that's sloppy and I want to insert it into a text file and have my program read from it, line by line, and insert it into the
code:
result=system("C:/Test/mc-wol.exe INSERT MAC HERE");
line. Is there an easy way to do this for somebody who knows very little C?

code:

#include<stdlib.h>
#include<stdio.h>

/* main() returns int, not void. */
int main( void ) 
{
int result ;
  result=system("C:/Test/mc-wol.exe 00:14:22:dd:a0:3c"); //computer 1
  result=system("C:/Test/mc-wol.exe dd:dd:dd:dd:dd:dd");  //computer 2
  result=system("C:/Test/mc-wol.exe aa:aa:aa:aa:aa:aa");  //computer 3
  system ("PAUSE" );
  return 0;
}

Does it need to be an exe? This is very easily doable in a batch script, and it sounds like you're more comfortable working on that level anyway.

The way you'd do this in C is you'd fopen your config file, use fread or fscanf to read each address into a buffer, use snprintf to fit that into your command, and then call system on that. It's prone to a ton of random little buffer overflows and other bugs, though, and it's ultimately going to be less flexible than a script.

hooah
Feb 6, 2006
WTF?
Why on earth does this
code:
        double T=0.0, c=0.0;

	cout << "Enter F: ";
	cin >> T;
	c=(5/9)*(T-32);
	cout << T << " F is " << c << " C" << endl;
give me a value of 0 for c no matter what I put in?

Captain Cappy
Aug 7, 2008

hooah posted:

Why on earth does this
code:
        double T=0.0, c=0.0;

	cout << "Enter F: ";
	cin >> T;
	c=(5/9)*(T-32);
	cout << T << " F is " << c << " C" << endl;
give me a value of 0 for c no matter what I put in?

5 / 9 is 0 when using integers. You need to do 5.0 / 9 in order to get it to actually be a fraction.

hooah
Feb 6, 2006
WTF?

Captain Cappy posted:

5 / 9 is 0 when using integers. You need to do 5.0 / 9 in order to get it to actually be a fraction.

Damnit, and I just read about that in the last chapter.

Morham
Jun 4, 2007
Hey guys I worked on this a bit more, and decided to try out the string compare (strcmp) function just for fun, in addition it seemed to do what I wanted. Anyway this all seems to work how I want it to!

code:
/* --- VARIABLES --- */

char* again[255];	//players response to playing again.
char* positive = "y";	//yes for string comparison.
char* negative = "n";	//no for string comparison.

/* --- MAIN --- */

do		
	{
	/*prompt player to play again, only accept y or n.*/
	printf("       Would you like to try again? (y/n): ");	
	scanf("%s", again);		
	}
	while (!((strcmp(again, positive, 1))==0||(strcmp(again, negative, 1))==0)); 
		
		
/* ---END--- */
I have in my head I should be using char* if I am using strings, and this time I have defined a memory space for user response so no over writing random memory. I think if you define the string it automatically asigns the correct amount of memory in the instance of:

char* positive = "y";

This would assign 1 bit of memory for the "y" (possibly two for the "y" and the invisible "\n"?) right?

ratbert90 posted:

If this is for class I really suggest the book "C Primer Plus". Its huge and incredibly well written for the basics of C and how things work. Its the book I used to teach myself C and then I went to college.

This isn't for class, I have no background in programming or even maths/IT/Science. It's all just out of a genuine interest in the subject and a desire to make interactive projects not just games, but interactive stories/animations and tools. I started following the tutorials over on WiBit and after finishing the section on C I am playing around and trying stuff out. This is my first attempt to do anything outside of tutorials and to be honest the fact it even remotely works is enough to encourage me to carry on learning.

However as some people have pointed out I have missed some nuances of the language and I am eager to get that right. It's not right until it's right.

Thank you for the suggestion on the book though I will look into getting some proper reading material soon.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Morham posted:

char* positive = "y";

This would assign 1 bit of memory for the "y" (possibly two for the "y" and the invisible "\n"?) right?
Two bytes, one for the 'y' and one for the '\0' that indicates the termination of a string ('\n' is a newline, the string can continue beyond it. scanf with a %s considers a newline to be end of string, because you can't read a '\0' from input.)

quote:

char* again[255];
This allocates 255 string pointers, not 255 characters.
char again[255]; is what you want; you can then use 'again' as if it were a char*.

I'm surprised your compiler isn't throwing up a warning or error on strcmp(again,positive), because in your code "again" is not (and doesn't decay to) a char*. You should probably turn on strict warnings when you're learning, to avoid getting into bad habits and wrong understandings.

evensevenone
May 12, 2001
Glass is a solid.
Learn pointers, arrays, and how C strings work ASAP, you'll kill yourself otherwise or at least waste ages trying figure out why nothing seems to work.

hooah
Feb 6, 2006
WTF?
I was working on a change calculator from the book, and I came up with this:
code:
int change=0, hd=0, q=0, d=0, n=0, p=0;
	
	cout << "Enter change [0...99]: ";
	cin >> change;
	hd=change/50;
	q=(change%50)/25;
	d=(change%25)/10;
	n=(change%10)/5;
	p=(change%5)/1;
	cout<< "Half(ves)  : " << hd << endl
		<< "Quarter(s) : " << q << endl
		<< "Dime(s)    : " << d << endl
		<< "Nickle(s)  : " << n << endl
		<< "Penny(ies) : " << p << endl;
However, the nickles show strange behavior - if the initial value of change isn’t a multiple of 5, the nickels are always one off (i.e. if change due is 87 cents, I have one too many nickels, but if it’s 84, I have one short). Why is this happening?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I don't think that's quite the problem - you'll probably find that 74 cents works fine, for example.

To help you work it out, how many nickels are you expecting to get from 87 cents? What's 87 % 10 going to give you? (Big hint coming next:) Is the combination of half-dollars, quarters and dimes you get back always going to add up to a multiple of 10 cents?

FlapYoJacks
Feb 12, 2009

hooah posted:

I was working on a change calculator from the book, and I came up with this:
code:
int change=0, hd=0, q=0, d=0, n=0, p=0;
	
	cout << "Enter change [0...99]: ";
	cin >> change;
	hd=change/50;
	q=(change%50)/25;
	d=(change%25)/10;
	n=(change%10)/5;
	p=(change%5)/1;
	cout<< "Half(ves)  : " << hd << endl
		<< "Quarter(s) : " << q << endl
		<< "Dime(s)    : " << d << endl
		<< "Nickle(s)  : " << n << endl
		<< "Penny(ies) : " << p << endl;
However, the nickles show strange behavior - if the initial value of change isn’t a multiple of 5, the nickels are always one off (i.e. if change due is 87 cents, I have one too many nickels, but if it’s 84, I have one short). Why is this happening?

I know it's not super helpful here, but have you considered a debugger? Most IDE's have them, and in the case of eclipse, you can just smash the debug symbol and then step through your code staring at the variables as they change. :) It may help quite a bit!

Hughlander
May 11, 2005

This made it's rounds today http://dl.dropboxusercontent.com/u/13100941/C%2B%2B11.pdf nice overview of the changes leading to C++ 11 in a slideshowish format.

BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER
So after today, I feel like I've got a firm grasp on what all needs to be done and can see the changes I need to make to my initial design to get everything running smoothly. But I ran into a circular dependency issue, I think it's just because it was that I was using pointers to full-bodied classes instead of using pointers to base classes. Just want to make sure I'm not putting a bandage over a big piece of bad design.

I have two classes, Record and Database, that need to know about each other to do certain thing. Neither has a the other as a member and they only get passed a pointer as an argument. Record serves double duty of not only being an instance of a record of a table but also knowing how it's table needs to be setup. Database just represent a connection to a database and handles all SQL commands for said database.

A table is created by calling Record.tableInit(Database *db) which, in turn, calls a db->addTable(). A new record is added to a table by calling Database.insert(Record *rec) which calls rec->toTable() (returns a pre-formated output string). If both of these classes were abstract base classes, would I still have the double dependency issue?

For those curious, my dirty hack was to use make a simple base for record that had the toTable() method and just used BaseRecord *rec in insert().

Cubiks
Aug 31, 2005
I wish I had something witty to put here...

BirdOfPlay posted:

A table is created by calling Record.tableInit(Database *db) which, in turn, calls a db->addTable(). A new record is added to a table by calling Database.insert(Record *rec) which calls rec->toTable() (returns a pre-formated output string). If both of these classes were abstract base classes, would I still have the double dependency issue?

Maybe I'm missing something, but this sort of dependency is quite easy to solve. In the header files of Record and Database, just forward declare the other class, and include both header files in the implementation files:

code:
// Record.h
class Database;
class Record {
  void tableInit(Database *db);
  ??? toTable();
  // other stuff
};

// Database.h
class Record;
class Database {
  void addTable(???);
  void insert(Record *rec);
  // other stuff
};

// Record.cpp
#include "Record.h"
#include "Database.h"
// Implement Record member functions here, can use all symbols from both headers

// Database.cpp
#include "Database.h"
#include "Record.h"
// Database implementation

ZombieApostate
Mar 13, 2011
Sorry, I didn't read your post.

I'm too busy replying to what I wish you said

:allears:

Hughlander posted:

This made it's rounds today http://dl.dropboxusercontent.com/u/13100941/C%2B%2B11.pdf nice overview of the changes leading to C++ 11 in a slideshowish format.

Holy crap I love you. That is so much easier to read than digging through all the proposals for additions and junk.

BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER

Cubiks posted:

Maybe I'm missing something, but this sort of dependency is quite easy to solve. In the header files of Record and Database, just forward declare the other class, and include both header files in the implementation files:

Yeah, maybe I missed that part when trying that.

Also, to be fair, I'm not using base classes to solve this issue for my main library. I'm using base classes because Database will have two distinct children, one for SQLite and another for PostGRES, while Record will have 14 children, at last count.

bobua
Mar 23, 2003
I'd trade it all for just a little more.

I'm a novice with c#(the only language I 'know') and trying to move a little project over to cpp. Pretty much baby's first program. I've just got a couple of general questions...

1. Can someone dumb down the -> operator? It appears to be used sorta like the . in c# but I see there is a . in some places too. I haven't had to use it yet, but I've seen it in some example code and had it called a 'pointer to' function but I haven't quite grasped it.

2. Am I crazy or to c++ programmers just despise long\descriptive variable names? Where I would expect to see lockedImage in c# I see limg in c++.

3. I have all the recommended books, but any general pointers or pitfalls you could see for someone trying to 'move backwards' from so little knowledge to a lower level language would be appreciated.

shrughes
Oct 11, 2008

(call/cc call/cc)

bobua posted:

I'm a novice with c#(the only language I 'know') and trying to move a little project over to cpp. Pretty much baby's first program. I've just got a couple of general questions...

1. Can someone dumb down the -> operator? It appears to be used sorta like the . in c# but I see there is a . in some places too. I haven't had to use it yet, but I've seen it in some example code and had it called a 'pointer to' function but I haven't quite grasped it.

The -> operator is to call methods and access fields of objects, given a pointer to said object. (Also when given a smart pointer.) The dot operator is for when you have a reference, or when the object's an lvalue or rvalue. So dot is consistent with dot used on C#'s struct instances, while -> is consistent with how you would use dot given a C# reference to a C# class instance.

bobua posted:

2. Am I crazy or to c++ programmers just despise long\descriptive variable names? Where I would expect to see lockedImage in c# I see limg in c++.

You're crazy, C++ programmers like descriptive variable names, and I'd expect `locked_image` or `lockedImage` to be the name in C++. You're probably looking at code written by some retard C programmer.

scissorman
Feb 7, 2011
Ramrod XTreme

bobua posted:

3. I have all the recommended books, but any general pointers or pitfalls you could see for someone trying to 'move backwards' from so little knowledge to a lower level language would be appreciated.
I would recommend using C++11, especially coming from a managed language like C#.
It provides useful features like the auto keyword to automatically determine the type of a variable as well as smart pointers, which allows you to avoid manually managing memory with new and delete, which is probably one of the biggest sources of bugs in C++.
Unfortunately most advice you'll find is for the older C++98; depending on what you want to do, you may also have problems with incompatible libraries.
More experienced developers might be able to tell you more about this.
I personally found the blog and presentations by Herb Sutter to be immensely useful.
Another related point is to use the standard library as much as possible.
It's not nearly as big as C#'s but provides excellent basic containers and algorithms.
Look at cppreference.com for a good online documentation.

raminasi
Jan 25, 2005

a last drink with no ice
The fact that autocompletion is usually not nearly as good in C++ as in C# puts some pressure on the descriptiveness of identifiers.

bobua
Mar 23, 2003
I'd trade it all for just a little more.

The biggest headache so far hasn't been the syntax or even pointers(i was scared after reading so much about how much other people are scared of them...)

It's that intellisense and exceptions don't seem helpful anymore... probably opencv's fault and not c++'s on intellisense, but I grappled for 3 days with a heap corruption error that I couldn't even figure out where in the code it was really coming from even when stepping through, turned out to be something to do with opencv and recompiling fixed it.


question...

code:
void CannyThreshold(int, void*) //edge detector
{
  /// Reduce noise with a kernel 3x3
  //blur( src_gray, detected_edges, Size(3,3) );

  /// Canny detector
  Canny( src_gray, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size );

  /// Using Canny's output as a mask, we display our result
  dst = Scalar::all(0);

  src.copyTo( dst, detected_edges);
  imshow( window_name, dst );
 } 
Why the "(int, void*)" part? I don't understand what it's doing.

bobua fucked around with this message at 03:17 on May 24, 2013

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Pretty much just a function that takes an int and a void* for parameters, then never bothers to use them. Might be there's another function out there that takes a function pointer (void)(int,void*) out there that needs this passed to it :shrug:

bobua
Mar 23, 2003
I'd trade it all for just a little more.

Is there even a way to use them without naming them like that?

tractor fanatic
Sep 9, 2005

Pillbug
No. MSVC and probably most other compilers will warn you if you don't use a parameter, but if you don't name the parameter it assumes you know what you're doing.

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
What is the point of an unused parameter warning? This can't be turned off on some of our builds and seems so pointless.

Telarra
Oct 9, 2012

baby puzzle posted:

What is the point of an unused parameter warning? This can't be turned off on some of our builds and seems so pointless.

The same as any other warning: to tell you "this is valid, but you probably hosed up here". If you're not using a parameter, you should typically just get rid of it.

And the unnamed parameters in that code snippet are probably for overloading purposes. Or just code rot, but hey, I'm feeling generous.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Right. The conventional way to suppress an unused-variable warning is to do (void) x; somewhere in the function (assuming you can't, you know, just remove the unused parameters.)

That Turkey Story
Mar 30, 2003

bobua posted:

1. Can someone dumb down the -> operator? It appears to be used sorta like the . in c# but I see there is a . in some places too. I haven't had to use it yet, but I've seen it in some example code and had it called a 'pointer to' function but I haven't quite grasped it.
Already explained, but this might also help -- when foo is a pointer, foo->bar is equivalent to (*foo).bar. It's just another way of writing it.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


That reminds me, if you've got an iterator to a list of pointers, is there any less-ugly way to call a method on those objects besides e.g. (*buttIter)->fart()?

FlapYoJacks
Feb 12, 2009
My suggestion is if you can, use EclipseCDT with G++/Mingw for C/C++ development.

It also may be beneficial to learn C before C++, as C++ is just C with classes thrown in. :v:

shrughes
Oct 11, 2008

(call/cc call/cc)

Ciaphas posted:

That reminds me, if you've got an iterator to a list of pointers, is there any less-ugly way to call a method on those objects besides e.g. (*buttIter)->fart()?

Just use `buttIter->->fart()` syntax.

only works on boner arrays

That Turkey Story
Mar 30, 2003

Ciaphas posted:

That reminds me, if you've got an iterator to a list of pointers, is there any less-ugly way to call a method on those objects besides e.g. (*buttIter)->fart()?

Boost has indirect_iterator, but I only really find it useful when working with generic algorithms.

Marta Velasquez
Mar 9, 2013

Good thing I was feeling suicidal this morning...
Fallen Rib

rjmccall posted:

Right. The conventional way to suppress an unused-variable warning is to do (void) x; somewhere in the function (assuming you can't, you know, just remove the unused parameters.)

If you're using gcc (not sure about others), you can tell the compiler that you meant to not use the variable with an attribute. It'll optimize calls to the function better, sometimes, too.

code:
void CannyThreshold( int __attribute__((unused)), void* __attribute__((unused)) ) //edge detector

xgalaxy
Jan 27, 2004
i write code

contrapants posted:

If you're using gcc (not sure about others), you can tell the compiler that you meant to not use the variable with an attribute. It'll optimize calls to the function better, sometimes, too.

code:
void CannyThreshold( int __attribute__((unused)), void* __attribute__((unused)) ) //edge detector

Why would you opt to use a compiler specific extension when you can just as easily not name the parameter or make a define with (void)x;

evensevenone
May 12, 2001
Glass is a solid.
It might be an implementation of a more general interface where other implantations do have parameters.

Canny is an edge detector right? There are lots of edge detection algorithms.

You could make the void* be an array of pointers and the int be the length of array, for a hilariously type-unsafe way to support an arbitrary number of arguments of arbitrary type. This is the kind of thing that C programmers love.

mobby_6kl
Aug 9, 2009

by Fluffdaddy
I was just dicking around with my (very basic) ray tracer on my laptop, and discovered that it seems to be roughly two times faster than running on the desktop where I originally wrote it. This wouldn't be too surprising since the laptop is like 5 years newer, but the processors are Core2 Q6600 and i7 2620m which should actually have similar overall and FLOPS performance, as far as I could tell from Intel's docs.

Both processors have 2M cache/core and 64-byte cache lines. The i7 supports AVX, but I was using the exact same binary on both machines, compiled with /arch not set using VS2012, optimized for speed and hardcoded to 4 worker threads. This more or less exhausted my ideas for explaining the performance difference. What else could I look into, because the newer processor can't be 4 times faster per core... can it?

Adbot
ADBOT LOVES YOU

Marta Velasquez
Mar 9, 2013

Good thing I was feeling suicidal this morning...
Fallen Rib

xgalaxy posted:

Why would you opt to use a compiler specific extension when you can just as easily not name the parameter or make a define with (void)x;

Leaving the parameter name out is a C++ thing. It's not valid in C.

code:
#include <stdio.h>

void testfunc (const char * message, int dummy)
{
    printf("%s", message);
}

int main (int argc, char * argv [])
{
    testfunc("Test\n", 0);
    return 0;
}
code:
[~] $ gcc -o test -Wall -Wextra test.c
test.c: In function ‘testfunc’:
test.c:3:42: warning: unused parameter ‘dummy’ [-Wunused-parameter]
test.c: In function ‘main’:
test.c:8:15: warning: unused parameter ‘argc’ [-Wunused-parameter]
test.c:8:28: warning: unused parameter ‘argv’ [-Wunused-parameter]
This doesn't compile:
code:
#include <stdio.h>

void testfunc (const char * message, int)
{
    printf("%s", message);
}

int main (int argc, char * argv [])
{
    testfunc("Test\n", 0);
    return 0;
}
code:
[~] $ gcc -o test2 -Wall -Wextra test.c
test.c: In function ‘testfunc’:
test.c:3:1: error: parameter name omitted
test.c: In function ‘main’:
test.c:8:15: warning: unused parameter ‘argc’ [-Wunused-parameter]
test.c:8:28: warning: unused parameter ‘argv’ [-Wunused-parameter]
This works just as well as __attribute__((unused)) :
code:
#include <stdio.h>

void testfunc (const char * message, int dummy)
{
    (void)dummy;
    
    printf("%s", message);
}

int main (int argc, char * argv [])
{
    testfunc("Test\n", 0);
    return 0;
}
code:
[~] $ gcc -o test3 -Wall -Wextra test.c
test.c: In function ‘main’:
test.c:10:15: warning: unused parameter ‘argc’ [-Wunused-parameter]
test.c:10:28: warning: unused parameter ‘argv’ [-Wunused-parameter]
I didn't know about the odd void cast. With optimizations enabled, it outputs the same binary as using the gcc attribute. I agree that this is a much cleaner and portable solution. Thanks for the info!

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply